diff --git a/README.md b/README.md index df60352..9b024ef 100644 --- a/README.md +++ b/README.md @@ -100,16 +100,6 @@ export default function RootLayout({ This convention is needed because the loader needs to know which files contain global styles and which don't. -## Config - -For details on the config options, see the [Linaria Config](https://github.com/callstack/linaria/blob/master/docs/CONFIGURATION.md). - -### Plugin specific config - -`enableInMemoryCache` (default: `true`). - -If set to `true`, the loader will generate a hash for the file content and store the transformed code in memory and only re-run the transformation if the file has changed. This can increase performance when working with large files. However, hashing the file content, even though it is pretty fast compared to the transformation, can still take some time. If you are experiencing performance or memory issues, you can disable this feature. - ## Good to know Because webpack 5 caches modules, the virtual CSS Modules need to be cached as well (so at that point the are not really virtual anymore, are they? Anyway...). They are placed in the same directory as where webpack puts its cache files. If the `next-with-linaria` cache is not in sync with the webpack cache anymore, it will cause errors due to missing CSS Modules. If you encounter such an error, you can delete the `.next/cache/webpack` folder and restart the dev server. diff --git a/src/loaders/transformLoader.ts b/src/loaders/transformLoader.ts index 8c26715..583caf5 100644 --- a/src/loaders/transformLoader.ts +++ b/src/loaders/transformLoader.ts @@ -6,13 +6,13 @@ * 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 type { PluginOptions, Preprocessor, Result, } from '@linaria/babel-preset'; import { transform } from '@linaria/babel-preset'; -import crypto from 'crypto'; import path from 'path'; import type { RawLoaderDefinitionFunction } from 'webpack'; @@ -26,15 +26,6 @@ export const regexLinariaGlobalCSS = /\.linaria\.global\.css$/; export const regexLinariaCSS = /\.linaria\.(module|global)\.css$/; export type LinariaLoaderOptions = { - /** - * Enable in-memory cache for transformed code. - * This can increase performance when working with big files. - * However, the downside is that every file needs to be hashed and - * is stored in memory. Disable this if you are experiencing memory issues. - * - * @default true - */ - enableInMemoryCache?: boolean; moduleStore: VirtualModuleStore; preprocessor?: Preprocessor; sourceMap?: boolean; @@ -60,44 +51,17 @@ function convertSourceMap( }; } -/** - * In-Memory cache for the transformed code. - */ -const cache = new Map< - string, - { - code: string; - hash: string; - sourceMap: string | undefined | any; - } ->(); - const transformLoader: LoaderType = function (content, inputSourceMap) { + // tell Webpack this loader is async + this.async(); + const { sourceMap = undefined, preprocessor = undefined, moduleStore, - enableInMemoryCache = true, ...rest } = this.getOptions() || {}; - let contentHash; - if (enableInMemoryCache) { - // create md5 hash of the file content - contentHash = crypto.createHash('md5').update(content).digest('hex'); - - // Check if we have a cached version of the transformed code - // so we don't have to re-run the transform if the file hasn't changed - const cacheEntry = cache.get(this.resourcePath); - if (cacheEntry?.hash === contentHash) { - this.callback(null, cacheEntry?.code, cacheEntry?.sourceMap); - return; - } - } - - // tell Webpack this loader is async - this.async(); - const asyncResolve = (token: string, importer: string): Promise => { const context = path.isAbsolute(importer) ? path.dirname(importer) @@ -165,17 +129,11 @@ const transformLoader: LoaderType = function (content, inputSourceMap) { ), ]); - const code = `${result.code}\n\nrequire("./${cssModuleName}");`; - - if (enableInMemoryCache) { - cache.set(this.resourcePath, { - code, - hash: contentHash, - sourceMap: result.sourceMap, - }); - } - - this.callback(null, code, result.sourceMap || undefined); + this.callback( + null, + `${result.code}\n\nrequire("./${cssModuleName}");`, + result.sourceMap ?? undefined, + ); } catch (err) { this.callback(err as Error); } @@ -183,15 +141,7 @@ const transformLoader: LoaderType = function (content, inputSourceMap) { return; } - if (enableInMemoryCache) { - cache.set(this.resourcePath, { - code: result.code, - hash: contentHash, - sourceMap: result.sourceMap, - }); - } - - this.callback(null, result.code, result.sourceMap || undefined); + this.callback(null, result.code, result.sourceMap ?? undefined); }, (err: Error) => this.callback(err), ); diff --git a/tests/example/apps/nextjs/build-and-bench.mjs b/tests/example/apps/nextjs/build-and-bench.mjs deleted file mode 100644 index d4eae84..0000000 --- a/tests/example/apps/nextjs/build-and-bench.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import { execSync } from 'child_process'; -import { promises as fs } from 'fs'; -import { join } from 'path'; -import prettyMs from 'pretty-ms'; -import { fileURLToPath } from 'url'; - -const CWD = join(fileURLToPath(import.meta.url), '..'); - -async function buildAndBench() { - // ignore error - await fs.rm('.next', { recursive: true, force: true }).catch(() => {}); - - execSync(`pnpm run build`, { - cwd: CWD, - stdio: 'inherit', - env: { - ...process.env, - TRACE_TARGET: 'jaeger', - }, - }); - const traceString = await fs.readFile(join(CWD, '.next', 'trace'), 'utf8'); - const traces = traceString - .split('\n') - .filter((line) => line) - .map((line) => JSON.parse(line)); - const { duration } = traces.pop().find(({ name }) => name === 'next-build'); - console.info('next build duration: ', prettyMs(duration / 1000)); -} - -buildAndBench(); diff --git a/tests/example/apps/nextjs/next.config.js b/tests/example/apps/nextjs/next.config.js index 6d0556d..7e60bbd 100644 --- a/tests/example/apps/nextjs/next.config.js +++ b/tests/example/apps/nextjs/next.config.js @@ -4,7 +4,7 @@ const withLinaria = require('../../../../'); const config = { experimental: { appDir: true, + transpilePackages: ['ui-kit'], }, - transpilePackages: ['ui-kit'], }; module.exports = withLinaria(config); diff --git a/tests/example/packages/ui-kit/generateBigFile.js b/tests/example/packages/ui-kit/generateBigFile.js deleted file mode 100644 index e7ca3ec..0000000 --- a/tests/example/packages/ui-kit/generateBigFile.js +++ /dev/null @@ -1,23 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const createBigFile = (size) => { - const file = fs.createWriteStream( - path.join(__dirname, 'linariaComponents.tsx'), - ); - file.write(`import { styled } from '@linaria/react';`); - for (let i = 0; i <= size; i++) { - file.write(` - export const StyledDiv${i} = styled.div\` - background: #fff; - border: 1px solid #000; - padding: 10px; - content: 'StyledDiv${i}'; - \`; - `); - } - - file.end(); -}; - -createBigFile(3_000);