diff --git a/README.md b/README.md index 790ce3e..fa69d7c 100644 --- a/README.md +++ b/README.md @@ -343,7 +343,7 @@ render(); ### API ```js -const {CracoRemoteComponentsPlugin, CracoLibsExamplePlugin, env} = require('@kne/modules-dev'); +const {CracoRemoteComponentsPlugin, CracoLibsExamplePlugin, CracoIsolateCopiedWebpackCachePlugin, env} = require('@kne/modules-dev'); ``` #### CracoRemoteComponentsPlugin @@ -354,6 +354,10 @@ const {CracoRemoteComponentsPlugin, CracoLibsExamplePlugin, env} = require('@kne |-----|----|----|-----| | middleware | 中间件配置 | object | undefined | +#### CracoIsolateCopiedWebpackCachePlugin + +将 webpack filesystem cache 的 `name` / `version` 绑定到当前 `appDir`,避免 workplace 拷贝原仓 `.cache` 后复用带原仓绝对路径的 pack(会去编译原仓 `src`,报 JSX preset 未开启)。`CracoRemoteComponentsPlugin` / `CracoLibsExamplePlugin` 已默认启用,一般不必再手动加。 + #### CracoLibsExamplePlugin 用于组件库示例项目的 Craco 插件,自动配置文档解析、版本管理和模块联邦支持。 diff --git a/index.js b/index.js index 7093993..224c6ae 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,14 @@ const CracoRemoteComponentsPlugin = require('./lib/craco-remote-components-plugin'); const CracoLibsExamplePlugin = require('./lib/craco-libs-example-plugin'); +const CracoIsolateCopiedWebpackCachePlugin = require('./lib/craco-isolate-copied-webpack-cache-plugin'); const env = require('./lib/env'); const buildComponentDocs = require('./lib/build-component-docs'); -module.exports = { CracoRemoteComponentsPlugin, CracoLibsExamplePlugin, env, buildComponentDocs }; +module.exports = { + CracoRemoteComponentsPlugin, + CracoLibsExamplePlugin, + CracoIsolateCopiedWebpackCachePlugin, + env, + buildComponentDocs +}; diff --git a/lib/craco-isolate-copied-webpack-cache-plugin.js b/lib/craco-isolate-copied-webpack-cache-plugin.js new file mode 100644 index 0000000..da00454 --- /dev/null +++ b/lib/craco-isolate-copied-webpack-cache-plugin.js @@ -0,0 +1,25 @@ +const path = require('path'); +const env = require('./env'); + +const getIsolateCopiedWebpackCacheName = (appDir = env.appDir) => `dev-${String(appDir).replace(/[^a-zA-Z0-9]+/g, '_')}`; + +// workplace rsync 会拷走原仓 .cache;webpack pack 记绝对路径。 +// 仅改 cacheDirectory 不够:name 仍是 default-development 时会复用原仓 pack,去编原仓 src。 +const isolateCopiedWebpackCache = (webpackConfig, appDir = env.appDir) => { + if (!webpackConfig.cache || typeof webpackConfig.cache !== 'object') { + return; + } + webpackConfig.cache.cacheDirectory = path.join(appDir, '.cache', 'webpack'); + webpackConfig.cache.name = getIsolateCopiedWebpackCacheName(appDir); + webpackConfig.cache.version = `${webpackConfig.cache.version || ''}|${appDir}`; +}; + +module.exports = { + overrideWebpackConfig({webpackConfig}) { + isolateCopiedWebpackCache(webpackConfig); + return webpackConfig; + } +}; + +module.exports.isolateCopiedWebpackCache = isolateCopiedWebpackCache; +module.exports.getIsolateCopiedWebpackCacheName = getIsolateCopiedWebpackCacheName; diff --git a/lib/craco-libs-example-plugin.js b/lib/craco-libs-example-plugin.js index 9164c51..ae5b16a 100644 --- a/lib/craco-libs-example-plugin.js +++ b/lib/craco-libs-example-plugin.js @@ -40,6 +40,8 @@ module.exports = { } }, { plugin: require('./craco-fix-plugin'), options: {} + }, { + plugin: require('./craco-isolate-copied-webpack-cache-plugin'), options: {} }); return cracoConfig; }, overrideWebpackConfig({webpackConfig, context}) { diff --git a/lib/craco-remote-components-plugin.js b/lib/craco-remote-components-plugin.js index b33d1e5..d4282dd 100644 --- a/lib/craco-remote-components-plugin.js +++ b/lib/craco-remote-components-plugin.js @@ -21,6 +21,8 @@ module.exports = { } }, { plugin: require('./craco-fix-plugin'), options: {} + }, { + plugin: require('./craco-isolate-copied-webpack-cache-plugin'), options: {} }); return cracoConfig; }, overrideWebpackConfig({webpackConfig, context}) { diff --git a/package.json b/package.json index 5d9896d..5add8ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kne/modules-dev", - "version": "2.4.13", + "version": "2.4.14", "description": "用于辅助在项目内启动一个规范化组件开发的环境", "publishConfig": { "access": "public", diff --git a/test/craco-isolate-copied-webpack-cache-plugin.test.js b/test/craco-isolate-copied-webpack-cache-plugin.test.js new file mode 100644 index 0000000..406d131 --- /dev/null +++ b/test/craco-isolate-copied-webpack-cache-plugin.test.js @@ -0,0 +1,46 @@ +const path = require('path'); +const { expect } = require('chai'); +const plugin = require('../lib/craco-isolate-copied-webpack-cache-plugin'); +const env = require('../lib/env'); + +const { getIsolateCopiedWebpackCacheName } = plugin; + +describe('craco-isolate-copied-webpack-cache-plugin', () => { + const createConfig = () => ({ + cache: { type: 'filesystem', cacheDirectory: '/tmp/shared-cache', version: 'hash' } + }); + + it('应将 webpack cache 指到项目 .cache/webpack,并用 appDir 生成 name/version', () => { + const webpackConfig = createConfig(); + plugin.overrideWebpackConfig({ webpackConfig, context: { env: 'development' } }); + expect(webpackConfig.cache.cacheDirectory).to.equal(path.resolve(env.appDir, '.cache/webpack')); + expect(webpackConfig.cache.name).to.equal(getIsolateCopiedWebpackCacheName(env.appDir)); + expect(webpackConfig.cache.version).to.equal(`hash|${env.appDir}`); + }); + + it('不同 appDir 应得到不同 cache.name', () => { + const a = getIsolateCopiedWebpackCacheName('/Users/me/.cursor_workplace/app/a'); + const b = getIsolateCopiedWebpackCacheName('/Users/me/Documents/Github/app'); + expect(a).to.not.equal(b); + }); + + it('没有 filesystem cache 时不抛错', () => { + const webpackConfig = {}; + plugin.overrideWebpackConfig({ webpackConfig, context: { env: 'development' } }); + expect(webpackConfig.cache).to.equal(undefined); + }); +}); + +describe('default plugins include isolateCopiedWebpackCache', () => { + const fs = require('fs'); + const remoteSrc = fs.readFileSync(path.join(__dirname, '../lib/craco-remote-components-plugin.js'), 'utf8'); + const libsSrc = fs.readFileSync(path.join(__dirname, '../lib/craco-libs-example-plugin.js'), 'utf8'); + + it('CracoRemoteComponentsPlugin 应默认加入该插件', () => { + expect(remoteSrc).to.include("require('./craco-isolate-copied-webpack-cache-plugin')"); + }); + + it('CracoLibsExamplePlugin 应默认加入该插件', () => { + expect(libsSrc).to.include("require('./craco-isolate-copied-webpack-cache-plugin')"); + }); +});