Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: correct entry script identification and webpack version detectio… #2800

Merged
merged 20 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .changeset/serious-nails-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@qiankunjs/webpack-plugin": patch
---

fix: correct entry script identification and webpack version detection in Vue CLI 5
2 changes: 2 additions & 0 deletions packages/webpack-plugin/README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ module.exports = {
plugins: [
new QiankunPlugin({
packageName: 'optionalPackageName', // 可选,如果不提供,将使用 package.json 中的名称
webpackVersion: '5', // 可选,项目使用的webpack大版本,若不提供插件会自动判断当前webpack版本
nayonglin marked this conversation as resolved.
Show resolved Hide resolved
entrySrcPattern: /<script[^>]*src="app.*\.js"[^>]*><\/script>/g, // 可选,用于匹配要添加entry属性的script标签的正则表达式。如果不提供,默认取html最后一个script标签
nayonglin marked this conversation as resolved.
Show resolved Hide resolved
}),
],
};
Expand Down
2 changes: 2 additions & 0 deletions packages/webpack-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ module.exports = {
plugins: [
new QiankunPlugin({
packageName: 'optionalPackageName', // Optional, if not provided, the name from package.json will be used
webpackVersion: '5', // Optional, specify the major version of webpack being used. If not provided, the version from package.json will be used by default.
entrySrcPattern: /<script[^>]*src="app.*\.js"[^>]*><\/script>/g, // Optional, a regex pattern to match specific script tags for adding the 'entry' attribute. Defaults to the last script tag if not specified.
}),
],
};
Expand Down
6 changes: 3 additions & 3 deletions packages/webpack-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"scripts": {
"build:webpack4": "cd ./tests/webpack4 && npm run build",
"build:webpack5": "cd ./tests/webpack5 && npm run build",
"test:local": "npm run build && npm run build:webpack4 && npm run build:webpack5 && vitest",
"build:webpack4": "cd ./tests/webpack4 && npm install && pnpm run build",
"build:webpack5": "cd ./tests/webpack5 && npm install && pnpm run build",
"test": "pnpm run build && pnpm run build:webpack4 && pnpm run build:webpack5 && vitest --run",
"build": "father build"
},
"files": ["dist"],
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-plugin/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('QiankunPlugin', () => {
expect(htmlContent).toContain('<script entry'); // 检查是否正确标记了 entry js

const jsChunkContent = fs.readFileSync(path.join(__dirname, 'tests/webpack4/dist/bundle.js'), 'utf-8');
expect(jsChunkContent).toContain('window.'); // 检查是否包含了 window. 关键字
expect(jsChunkContent).toMatch(/window(\["[^"]+"\]|\.\w+)/); // 检查是否包含了 window. 或 window["..."] 关键字
});

// webpack5
Expand All @@ -20,6 +20,6 @@ describe('QiankunPlugin', () => {
expect(htmlContent).toContain('<script entry'); // 检查是否正确标记了 entry js

const jsChunkContent = fs.readFileSync(path.join(__dirname, 'tests/webpack5/dist/bundle.js'), 'utf-8');
expect(jsChunkContent).toContain('window.'); // 检查是否包含了 window. 关键字
expect(jsChunkContent).toMatch(/window(\["[^"]+"\]|\.\w+)/); // 检查是否包含了 window. 或 window["..."] 关键字
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里直接检查 window.${packageName} 吧

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里直接检查 window.${packageName} 吧

已加上包名,不过同时判断了.符号和中括号的形式,因为发现在某些场景下webpack产物是中括号的这种形式

});
});
25 changes: 14 additions & 11 deletions packages/webpack-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { RawSource } from 'webpack-sources';

interface QiankunPluginOptions {
packageName?: string;
webpackVersion?: string;
entrySrcPattern?: RegExp; // 新增可选参数,用于匹配script标签
}

interface PackageJson {
Expand All @@ -15,10 +17,15 @@ interface PackageJson {

class QiankunPlugin {
private packageName: string;
private webpackVersion: string; // 用户指定的webpack版本
private entrySrcPattern: RegExp; // 用户提供的正则表达式

private static packageJson: PackageJson = QiankunPlugin.readPackageJson();

constructor(options: QiankunPluginOptions = {}) {
this.packageName = options.packageName || QiankunPlugin.packageJson.name || '';
this.webpackVersion = options.webpackVersion || ''; // 使用用户指定的webapck版本
this.entrySrcPattern = options.entrySrcPattern || /<script[^>]*src="[^"]+"[^>]*><\/script>/g; // 使用用户提供的正则或默认值
}

private static readPackageJson(): PackageJson {
Expand All @@ -27,10 +34,6 @@ class QiankunPlugin {
return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) as PackageJson;
}

private static getWebpackVersion(): string {
return QiankunPlugin.packageJson.dependencies?.webpack || QiankunPlugin.packageJson.devDependencies?.webpack || '';
}

apply(compiler: Compiler): void {
this.configureWebpackOutput(compiler);
compiler.hooks.emit.tapAsync('QiankunPlugin', (compilation: Compilation, callback: () => void) => {
Expand All @@ -40,16 +43,17 @@ class QiankunPlugin {
}

private configureWebpackOutput(compiler: Compiler): void {
const webpackVersion = QiankunPlugin.getWebpackVersion();
const webpackCompilerOptions = compiler.options as Configuration & { output: { jsonpFunction?: string } };
if (webpackVersion.startsWith('4')) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const version = this.webpackVersion || compiler.webpack?.version || '4';
if (version.startsWith('4')) {
// webpack 4
webpackCompilerOptions.output.library = `${this.packageName}`;
webpackCompilerOptions.output.libraryTarget = 'window';
webpackCompilerOptions.output.jsonpFunction = `webpackJsonp_${this.packageName}`;
webpackCompilerOptions.output.globalObject = 'window';
webpackCompilerOptions.output.chunkLoadingGlobal = `webpackJsonp_${this.packageName}`;
} else if (webpackVersion.startsWith('5')) {
} else if (version.startsWith('5')) {
// webpack 5
webpackCompilerOptions.output.library = {
name: `${this.packageName}`,
Expand All @@ -76,11 +80,10 @@ class QiankunPlugin {
}

private addEntryAttributeToScripts(htmlString: string): string {
const scriptTags = htmlString.match(/<script[^>]*src="[^"]+"[^>]*><\/script>/g) || [];
const nonAsyncOrDeferScripts = scriptTags.filter((tag) => !/defer|async/.test(tag));
const scriptTags = htmlString.match(this.entrySrcPattern) || [];

if (nonAsyncOrDeferScripts.length) {
const lastScriptTag = nonAsyncOrDeferScripts[nonAsyncOrDeferScripts.length - 1];
if (scriptTags.length) {
const lastScriptTag = scriptTags[scriptTags.length - 1];
const modifiedScriptTag = lastScriptTag.replace('<script', '<script entry');
return htmlString.replace(lastScriptTag, modifiedScriptTag);
}
Expand Down
1 change: 1 addition & 0 deletions packages/webpack-plugin/tests/webpack4/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
</head>
<body>
<div id="app"></div>
<script src="/js/app.12.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion packages/webpack-plugin/tests/webpack4/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"devDependencies": {
"html-webpack-plugin": "^4.5.2",
"webpack": "4",
"webpack-cli": "3"
"webpack-cli": "4"
}
}
5 changes: 4 additions & 1 deletion packages/webpack-plugin/tests/webpack4/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ module.exports = {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'development',
plugins: [
new HtmlWebpackPlugin({
template: './index.html', // 指定模板文件路径
filename: 'index.html', // 输出的HTML文件名(默认为index.html)
}),
new QiankunPlugin(),
new QiankunPlugin({
entrySrcPattern: /<script[^>]*src="\/js\/app.*.js"[^>]*><\/script>/g,
}),
],
};
2 changes: 1 addition & 1 deletion packages/webpack-plugin/tests/webpack5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"devDependencies": {
"html-webpack-plugin": "^5.5.3",
"webpack": "5",
"webpack-cli": "4"
"webpack-cli": "5"
}
}
5 changes: 4 additions & 1 deletion packages/webpack-plugin/tests/webpack5/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ module.exports = {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'development',
plugins: [
new HtmlWebpackPlugin({
template: './index.html', // 指定模板文件路径
filename: 'index.html', // 输出的HTML文件名(默认为index.html)
scriptLoading: 'blocking',
}),
new QiankunPlugin(),
new QiankunPlugin({
webpackVersion: '5',
}),
],
};