Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@ example

prompts
graphify-out
.modules-dev
28 changes: 26 additions & 2 deletions lib/craco-fix-plugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
const {when} = require("@kne/craco");
const env = require("./env");

const allowReadmeOutsideSrc = (webpackConfig) => {
const plugins = webpackConfig.resolve && webpackConfig.resolve.plugins;
if (!Array.isArray(plugins)) {
return;
}
const scopePlugin = plugins.find((plugin) => plugin && plugin.constructor && plugin.constructor.name === 'ModuleScopePlugin');
if (!scopePlugin) {
return;
}
if (scopePlugin.allowedFiles && typeof scopePlugin.allowedFiles.add === 'function') {
scopePlugin.allowedFiles.add(env.readmeIndexPath);
scopePlugin.allowedFiles.add(env.manifestPath);
}
if (Array.isArray(scopePlugin.allowedPaths) && !scopePlugin.allowedPaths.includes(env.readmeDir)) {
scopePlugin.allowedPaths.push(env.readmeDir);
}
};

module.exports = {
overrideWebpackConfig({webpackConfig, context}) {
if (context.env === 'production') {
Expand All @@ -17,7 +36,11 @@ module.exports = {
}
});
}
webpackConfig.resolve.fallback = {
webpackConfig.resolve = webpackConfig.resolve || {};
webpackConfig.resolve.alias = Object.assign({}, webpackConfig.resolve.alias, {
readme: env.readmeDir
});
webpackConfig.resolve.fallback = Object.assign({}, webpackConfig.resolve.fallback, {
"path": false,
"util": false,
"url": false,
Expand All @@ -28,7 +51,8 @@ module.exports = {
"querystring": false,
"zlib": false,
"fs": false
};
});
allowReadmeOutsideSrc(webpackConfig);
return webpackConfig;
}
};
9 changes: 7 additions & 2 deletions lib/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ const ensureSlash = require('@kne/ensure-slash');
const template = require('lodash/template');

const appDir = process.cwd();
const manifestPath = path.resolve(appDir, 'node_modules/readme/modules.js');
// 虚拟 readme 不能放在 node_modules 下:workplace 软链 node_modules 时 webpack
// 会 realpath 到 SOURCE,找不到虚拟文件。
const modulesDevDir = path.resolve(appDir, '.modules-dev');
const readmeDir = path.resolve(modulesDevDir, 'readme');
const manifestPath = path.resolve(readmeDir, 'modules.js');
const readmeIndexPath = path.resolve(readmeDir, 'index.js');

const env = {
appDir, manifestPath
appDir, modulesDevDir, readmeDir, manifestPath, readmeIndexPath
};

Object.defineProperties(env, {
Expand Down
32 changes: 29 additions & 3 deletions lib/readme-webpack-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ const buildComponentDocs = require('./build-component-docs');

const ReadmeWebpackPlugin_MODULE_NAMES = 'ReadmeWebpackPlugin_MODULE_NAMES';

/** 将虚拟 readme 同步到磁盘(内容不变则不写,避免 watch 循环)。workplace 软链 node_modules 时供 source-map-loader realpath。 */
const writeReadmeFilesIfChanged = (files) => {
fs.ensureDirSync(env.readmeDir);
Object.entries(files).forEach(([file, content]) => {
let prev = null;
try {
prev = fs.readFileSync(file, 'utf8');
} catch (e) {
prev = null;
}
if (prev !== content) {
fs.writeFileSync(file, content);
}
});
};

/** 将完整聚合文档写入 webpack 输出目录的 README.md(与 remoteEntry.js 同级)。 */
const writeFullReadmeToOutput = async ({ content, outputPath }) => {
if (content == null || content === '') {
Expand Down Expand Up @@ -48,14 +64,24 @@ class ReadmeWebpackPlugin {
const moduleNames = compilation.params[ReadmeWebpackPlugin_MODULE_NAMES];
const readmes = `${moduleNames.map(({ name }) => `import ${camelCase(name)} from '${env.moduleAliasName}/${name}/README.md';`).join('\n')}export default {${moduleNames.map(({ name }) => camelCase(name)).join(',')}};`;

virtualModules.writeModule(env.manifestPath, readmes + `\nexport const manifest = ${JSON.stringify(Object.assign({
const manifestSource = readmes + `\nexport const manifest = ${JSON.stringify(Object.assign({
'name': env.componentsName,
'version': env.componentsVersion,
'open-version': env.openComponentsVersion,
'public-url': env.publicUrl,
'modules': moduleNames
}))};`);
virtualModules.writeModule('node_modules/readme/index.js', readmes);
}))};`;
virtualModules.writeModule(env.manifestPath, manifestSource);
virtualModules.writeModule(env.readmeIndexPath, readmes);
writeReadmeFilesIfChanged({
[env.readmeIndexPath]: readmes,
[env.manifestPath]: manifestSource,
[path.join(env.readmeDir, 'package.json')]: JSON.stringify({
name: 'readme',
main: 'index.js',
private: true
})
});
});
// production:写入完整聚合 README.md(与根目录 TOC 版 README 无关)
compiler.hooks.afterEmit.tapPromise('ReadmeWebpackPlugin', async () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kne/modules-dev",
"version": "2.4.10",
"version": "2.4.11",
"description": "用于辅助在项目内启动一个规范化组件开发的环境",
"publishConfig": {
"access": "public",
Expand Down
12 changes: 11 additions & 1 deletion test/craco-fix-plugin.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const { expect } = require('chai');
const plugin = require('../lib/craco-fix-plugin');
const env = require('../lib/env');

const createConfig = (concatenateModules = true) => ({
plugins: [],
optimization: { concatenateModules },
resolve: {}
resolve: { alias: {}, plugins: [] }
});

describe('craco-fix-plugin concatenateModules', () => {
Expand All @@ -20,3 +21,12 @@ describe('craco-fix-plugin concatenateModules', () => {
expect(webpackConfig.optimization.concatenateModules).to.equal(true);
});
});

describe('craco-fix-plugin readme alias', () => {
it('应将 readme 别名到 .modules-dev/readme', () => {
const webpackConfig = createConfig(true);
plugin.overrideWebpackConfig({ webpackConfig, context: { env: 'development' } });
expect(webpackConfig.resolve.alias.readme).to.equal(env.readmeDir);
});
});

13 changes: 13 additions & 0 deletions test/env.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const path = require('path');
const { expect } = require('chai');
const env = require('../lib/env');

describe('env readme paths', () => {
it('虚拟 readme 应落在 .modules-dev 下而不是 node_modules', () => {
expect(env.readmeDir).to.equal(path.resolve(process.cwd(), '.modules-dev/readme'));
expect(env.readmeIndexPath).to.equal(path.resolve(env.readmeDir, 'index.js'));
expect(env.manifestPath).to.equal(path.resolve(env.readmeDir, 'modules.js'));
expect(env.manifestPath.includes(`${path.sep}node_modules${path.sep}`)).to.equal(false);
expect(env.readmeIndexPath.includes(`${path.sep}node_modules${path.sep}`)).to.equal(false);
});
});