From a281440271cb29d4d2e2b0cb3b2fee26f1e4bc69 Mon Sep 17 00:00:00 2001 From: Anton Evzhakov Date: Wed, 1 Dec 2021 14:21:21 +0200 Subject: [PATCH] fix(webpack): replace fs cache with in-memory cache (fixes #878) --- package.json | 1 - src/loader.ts | 62 +++++++++--------------------------------- src/outputCssLoader.ts | 9 ++++++ yarn.lock | 17 ------------ 4 files changed, 22 insertions(+), 67 deletions(-) create mode 100644 src/outputCssLoader.ts diff --git a/package.json b/package.json index 6a61f98e8..4b54c7304 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,6 @@ "cosmiconfig": "^5.1.0", "debug": "^4.1.1", "enhanced-resolve": "^4.1.0", - "find-yarn-workspace-root": "^1.2.1", "glob": "^7.1.3", "loader-utils": "^1.2.3", "mkdirp": "^0.5.1", diff --git a/src/loader.ts b/src/loader.ts index fd172bce3..b11e62e06 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -4,29 +4,20 @@ * 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 * as EvalCache from './babel/eval-cache'; import Module from './babel/module'; import { debug } from './babel/utils/logger'; import transform from './transform'; - -const workspaceRoot = findYarnWorkspaceRoot(); -const lernaConfig = cosmiconfig('lerna', { - searchPlaces: ['lerna.json'], -}).searchSync(); -const lernaRoot = - lernaConfig !== null ? path.dirname(lernaConfig.filepath) : null; +import { addFile } from './outputCssLoader'; type LoaderContext = Parameters[0]; +const outputCssLoader = require.resolve('./outputCssLoader'); + export default function loader( this: LoaderContext, content: string, @@ -38,26 +29,12 @@ export default function loader( const { sourceMap = undefined, - cacheDirectory = '.linaria-cache', preprocessor = undefined, extension = '.linaria.css', ...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 outputFilename = this.resourcePath.replace(/\.[^.]+$/, extension); const resolveOptions = { extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], @@ -84,13 +61,15 @@ export default function loader( try { // Use webpack's resolution when evaluating modules - Module._resolveFilename = (id, { filename }) => - resolveSync(path.dirname(filename), id); + 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, }); @@ -121,28 +100,13 @@ export default function loader( }); } - // 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); - } + addFile(this.resourcePath, cssText); + const request = `${outputFilename}!=!${outputCssLoader}!${this.resourcePath}`; + const stringifiedRequest = loaderUtils.stringifyRequest(this, request); this.callback( null, - `${result.code}\n\nrequire(${loaderUtils.stringifyRequest( - this, - outputFilename - )});`, + `${result.code}\n\nrequire(${stringifiedRequest});`, result.sourceMap ?? undefined ); return; diff --git a/src/outputCssLoader.ts b/src/outputCssLoader.ts new file mode 100644 index 000000000..27916a76f --- /dev/null +++ b/src/outputCssLoader.ts @@ -0,0 +1,9 @@ +const cssLookup = new Map(); + +export const addFile = (id: string, content: string) => { + cssLookup.set(id, content); +}; + +export default function outputCssLoader(this: { resourcePath: string }) { + return cssLookup.get(this.resourcePath) ?? ''; +} diff --git a/yarn.lock b/yarn.lock index 7edbc7fe7..012710047 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4114,14 +4114,6 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-yarn-workspace-root@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" - integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== - dependencies: - fs-extra "^4.0.3" - micromatch "^3.1.4" - flat-cache@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" @@ -4178,15 +4170,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-extra@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"