summaryrefslogtreecommitdiff
path: root/@linaria/packages/webpack4-loader
diff options
context:
space:
mode:
Diffstat (limited to '@linaria/packages/webpack4-loader')
-rw-r--r--@linaria/packages/webpack4-loader/CHANGELOG.md54
-rw-r--r--@linaria/packages/webpack4-loader/README.md35
-rw-r--r--@linaria/packages/webpack4-loader/babel.config.js3
-rw-r--r--@linaria/packages/webpack4-loader/package.json61
-rw-r--r--@linaria/packages/webpack4-loader/src/index.ts167
-rw-r--r--@linaria/packages/webpack4-loader/tsconfig.json5
6 files changed, 325 insertions, 0 deletions
diff --git a/@linaria/packages/webpack4-loader/CHANGELOG.md b/@linaria/packages/webpack4-loader/CHANGELOG.md
new file mode 100644
index 0000000..c8fca74
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/CHANGELOG.md
@@ -0,0 +1,54 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+# [3.0.0-beta.7](https://github.com/callstack/linaria/compare/v3.0.0-beta.6...v3.0.0-beta.7) (2021-06-24)
+
+
+### Bug Fixes
+
+* webpack resolve options ([#785](https://github.com/callstack/linaria/issues/785)) ([64b2b06](https://github.com/callstack/linaria/commit/64b2b06edd873d7db0f36ef25a4b9d8389808eb2))
+
+
+
+
+
+# [3.0.0-beta.6](https://github.com/callstack/linaria/compare/v3.0.0-beta.5...v3.0.0-beta.6) (2021-06-06)
+
+
+### Bug Fixes
+
+* **webpack:** hot reload fails after compile error (fixes [#762](https://github.com/callstack/linaria/issues/762)) ([#775](https://github.com/callstack/linaria/issues/775)) ([67fcd81](https://github.com/callstack/linaria/commit/67fcd8108f283f8ade23c68ad3fece8aee335bf1))
+
+
+
+
+
+# [3.0.0-beta.5](https://github.com/callstack/linaria/compare/v3.0.0-beta.4...v3.0.0-beta.5) (2021-05-31)
+
+**Note:** Version bump only for package @linaria/webpack4-loader
+
+
+
+
+
+# [3.0.0-beta.4](https://github.com/callstack/linaria/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2021-05-07)
+
+**Note:** Version bump only for package @linaria/webpack4-loader
+
+
+
+
+
+# [3.0.0-beta.3](https://github.com/callstack/linaria/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2021-04-20)
+
+**Note:** Version bump only for package @linaria/webpack4-loader
+
+
+
+
+
+# [3.0.0-beta.2](https://github.com/callstack/linaria/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2021-04-11)
+
+**Note:** Version bump only for package @linaria/webpack4-loader
diff --git a/@linaria/packages/webpack4-loader/README.md b/@linaria/packages/webpack4-loader/README.md
new file mode 100644
index 0000000..0d75b37
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/README.md
@@ -0,0 +1,35 @@
+<p align="center">
+ <img alt="Linaria" src="https://raw.githubusercontent.com/callstack/linaria/HEAD/website/assets/linaria-logo@2x.png" width="496">
+</p>
+
+<p align="center">
+Zero-runtime CSS in JS library.
+</p>
+
+---
+
+### 📖 Please refer to the [GitHub](https://github.com/callstack/linaria#readme) for full documentation.
+
+## Features
+
+- Write CSS in JS, but with **zero runtime**, CSS is extracted to CSS files during build
+- Familiar **CSS syntax** with Sass like nesting
+- Use **dynamic prop based styles** with the React bindings, uses CSS variables behind the scenes
+- Easily find where the style was defined with **CSS sourcemaps**
+- **Lint your CSS** in JS with [stylelint](https://github.com/stylelint/stylelint)
+- Use **JavaScript for logic**, no CSS preprocessor needed
+- Optionally use any **CSS preprocessor** such as Sass or PostCSS
+
+**[Why use Linaria](../../docs/BENEFITS.md)**
+
+## Installation
+
+```sh
+npm install @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker
+```
+
+or
+
+```sh
+yarn add @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker
+```
diff --git a/@linaria/packages/webpack4-loader/babel.config.js b/@linaria/packages/webpack4-loader/babel.config.js
new file mode 100644
index 0000000..c9ad680
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/babel.config.js
@@ -0,0 +1,3 @@
+const config = require('../../babel.config');
+
+module.exports = config;
diff --git a/@linaria/packages/webpack4-loader/package.json b/@linaria/packages/webpack4-loader/package.json
new file mode 100644
index 0000000..c7fdf8a
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/package.json
@@ -0,0 +1,61 @@
+{
+ "name": "@linaria/webpack4-loader",
+ "version": "3.0.0-beta.7",
+ "publishConfig": {
+ "access": "public"
+ },
+ "description": "Blazing fast zero-runtime CSS in JS library",
+ "main": "lib/index.js",
+ "module": "esm/index.js",
+ "types": "types",
+ "files": [
+ "types/",
+ "lib/",
+ "esm/"
+ ],
+ "license": "MIT",
+ "repository": "git@github.com:callstack/linaria.git",
+ "bugs": {
+ "url": "https://github.com/callstack/linaria/issues"
+ },
+ "homepage": "https://github.com/callstack/linaria#readme",
+ "keywords": [
+ "react",
+ "linaria",
+ "css",
+ "css-in-js",
+ "styled-components",
+ "babel-plugin",
+ "babel"
+ ],
+ "scripts": {
+ "build:lib": "cross-env NODE_ENV=legacy babel src --out-dir lib --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
+ "build:esm": "babel src --out-dir esm --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
+ "build": "yarn build:lib && yarn build:esm",
+ "build:declarations": "tsc --emitDeclarationOnly --outDir types",
+ "prepare": "yarn build && yarn build:declarations",
+ "typecheck": "tsc --noEmit --composite false",
+ "watch": "yarn build --watch"
+ },
+ "devDependencies": {
+ "@types/cosmiconfig": "^5.0.3",
+ "@types/enhanced-resolve": "^3.0.6",
+ "@types/loader-utils": "^1.1.3",
+ "@types/mkdirp": "^0.5.2",
+ "@types/normalize-path": "^3.0.0",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "@linaria/babel-preset": "^3.0.0-beta.7",
+ "@linaria/logger": "^3.0.0-beta.3",
+ "cosmiconfig": "^5.1.0",
+ "enhanced-resolve": "^4.1.0",
+ "find-yarn-workspace-root": "^1.2.1",
+ "loader-utils": "^1.2.3",
+ "mkdirp": "^0.5.1",
+ "normalize-path": "^3.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7"
+ }
+}
diff --git a/@linaria/packages/webpack4-loader/src/index.ts b/@linaria/packages/webpack4-loader/src/index.ts
new file mode 100644
index 0000000..c55329a
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/src/index.ts
@@ -0,0 +1,167 @@
+/**
+ * This file contains a Webpack loader for Linaria.
+ * It uses the transform.ts function to generate class names from source code,
+ * returns transformed code without template literals and attaches generated source maps
+ */
+
+import fs from 'fs';
+import path from 'path';
+import mkdirp from 'mkdirp';
+import normalize from 'normalize-path';
+import loaderUtils from 'loader-utils';
+import enhancedResolve from 'enhanced-resolve';
+import findYarnWorkspaceRoot from 'find-yarn-workspace-root';
+import type { RawSourceMap } from 'source-map';
+import cosmiconfig from 'cosmiconfig';
+import { EvalCache, Module, transform } from '@linaria/babel-preset';
+import { debug } from '@linaria/logger';
+
+const workspaceRoot = findYarnWorkspaceRoot();
+const lernaConfig = cosmiconfig('lerna', {
+ searchPlaces: ['lerna.json'],
+}).searchSync();
+const lernaRoot =
+ lernaConfig !== null ? path.dirname(lernaConfig.filepath) : null;
+
+type LoaderContext = Parameters<typeof loaderUtils.getOptions>[0];
+
+const castSourceMap = <T extends { version: number } | { version: string }>(
+ sourceMap: T | null | undefined
+) =>
+ sourceMap
+ ? {
+ ...sourceMap,
+ version: sourceMap.version.toString(),
+ }
+ : undefined;
+
+export default function webpack4Loader(
+ this: LoaderContext,
+ content: string,
+ inputSourceMap: RawSourceMap | null
+) {
+ debug('loader', this.resourcePath);
+
+ EvalCache.clearForFile(this.resourcePath);
+
+ const resolveOptionsDefaults = {
+ conditionNames: ['require'],
+ extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
+ };
+
+ const {
+ sourceMap = undefined,
+ cacheDirectory = '.linaria-cache',
+ preprocessor = undefined,
+ extension = '.linaria.css',
+ resolveOptions = {},
+ ...rest
+ } = loaderUtils.getOptions(this) || {};
+
+ const root = workspaceRoot || lernaRoot || process.cwd();
+
+ const baseOutputFileName = this.resourcePath.replace(/\.[^.]+$/, extension);
+
+ const outputFilename = normalize(
+ path.join(
+ path.isAbsolute(cacheDirectory)
+ ? cacheDirectory
+ : path.join(process.cwd(), cacheDirectory),
+ this.resourcePath.includes(root)
+ ? path.relative(root, baseOutputFileName)
+ : baseOutputFileName
+ )
+ );
+
+ const resolveSync = enhancedResolve.create.sync(
+ // this._compilation is a deprecated API
+ // However there seems to be no other way to access webpack's resolver
+ // There is this.resolve, but it's asynchronous
+ // Another option is to read the webpack.config.js, but it won't work for programmatic usage
+ // This API is used by many loaders/plugins, so hope we're safe for a while
+ {
+ ...resolveOptionsDefaults,
+ ...((this._compilation?.options.resolve && {
+ alias: this._compilation.options.resolve.alias,
+ modules: this._compilation.options.resolve.modules,
+ }) ||
+ {}),
+ ...resolveOptions,
+ }
+ );
+
+ let result;
+
+ const originalResolveFilename = Module._resolveFilename;
+
+ try {
+ // Use webpack's resolution when evaluating modules
+ Module._resolveFilename = (id, { filename }) => {
+ const result = resolveSync(path.dirname(filename), id);
+ this.addDependency(result);
+ return result;
+ };
+
+ result = transform(content, {
+ filename: path.relative(process.cwd(), this.resourcePath),
+ inputSourceMap: inputSourceMap ?? undefined,
+ outputFilename,
+ pluginOptions: rest,
+ preprocessor,
+ });
+ } finally {
+ // Restore original behaviour
+ Module._resolveFilename = originalResolveFilename;
+ }
+
+ if (result.cssText) {
+ let { cssText } = result;
+
+ if (sourceMap) {
+ cssText += `/*# sourceMappingURL=data:application/json;base64,${Buffer.from(
+ result.cssSourceMapText || ''
+ ).toString('base64')}*/`;
+ }
+
+ if (result.dependencies?.length) {
+ result.dependencies.forEach((dep) => {
+ try {
+ const f = resolveSync(path.dirname(this.resourcePath), dep);
+
+ this.addDependency(f);
+ } catch (e) {
+ // eslint-disable-next-line no-console
+ console.warn(`[linaria] failed to add dependency for: ${dep}`, e);
+ }
+ });
+ }
+
+ // Read the file first to compare the content
+ // Write the new content only if it's changed
+ // This will prevent unnecessary WDS reloads
+ let currentCssText;
+
+ try {
+ currentCssText = fs.readFileSync(outputFilename, 'utf-8');
+ } catch (e) {
+ // Ignore error
+ }
+
+ if (currentCssText !== cssText) {
+ mkdirp.sync(path.dirname(outputFilename));
+ fs.writeFileSync(outputFilename, cssText);
+ }
+
+ this.callback(
+ null,
+ `${result.code}\n\nrequire(${loaderUtils.stringifyRequest(
+ this,
+ outputFilename
+ )});`,
+ castSourceMap(result.sourceMap)
+ );
+ return;
+ }
+
+ this.callback(null, result.code, castSourceMap(result.sourceMap));
+}
diff --git a/@linaria/packages/webpack4-loader/tsconfig.json b/@linaria/packages/webpack4-loader/tsconfig.json
new file mode 100644
index 0000000..0b7f756
--- /dev/null
+++ b/@linaria/packages/webpack4-loader/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": { "paths": {}, "rootDir": "src/" },
+ "references": [{ "path": "../babel" }, { "path": "../logger" }]
+}