Skip to content

Commit

Permalink
新增清理绝对路径配置项以解决Firefox扩展问题
Browse files Browse the repository at this point in the history
新增配置项`clearAbsPath`,用于在构建后清理代码中的绝对路径变量,确保不同环境下的构建产物一致性,满足Firefox扩展的要求。此功能在v1.1.4版本中添加。
  • Loading branch information
kukushouhou committed Oct 6, 2024
1 parent 77e8abb commit 4541ee4
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default {
| splitChunks | boolean | `true` | During `build`, whether to split all modules reused two or more times in the content script, options page, and popup page into the `vendor.js` file. Background scripts can only define a single JS file and therefore do not participate in the splitting. |`build`时是否将内容脚本、选项页、弹出页复用2次及以上的全部模块均切分到`vendor.js`文件中,后台脚本只能定义单一js文件因此不参与切分。 | - |
| splitChunksPathName | string | `chunks` | The folder name where the split `vendor.js` file is stored by default is `chunks`. | 切分后的`vendor.js`文件存放文件夹名称,默认为`chunks`| - |
| targets | string[] | `['chrome']` | Specifies the target browsers for compilation. The default is to compile only for Chrome extensions. Currently, the available options are `chrome`, `chrome102` and `firefox`. Multiple selections are allowed, and when multiple targets are selected, the `dev` and `build` commands will generate compiled files for all specified target browsers simultaneously. | 编译的目标浏览器。默认为只编译Chrome扩展,目前的可选值为`chrome``chrome102``firefox`,可多选,多选后`dev``build`时将同时分别生成出目标浏览器的编译文件。 | v1.1.0 |
| clearAbsPath | boolean or string | `true` | Cleans absolute path variables in the code before compression to ensure consistent build outputs across different systems and paths. Firefox requires that the compiled output must be identical to the uploaded files in any environment, hence the need to clean absolute path variables. | 编译后即将压缩代码前清理代码中的绝对路径变量,以解决不同系统、不同路径下构建后的产物未能完全一致的问题。Firefox要求任意环境下编译后产物必须和上传的文件一致,因此需要清理绝对路径变量。 | v1.1.4 |

### Guidelines for writing the `manifest.json` source file. | `manifest.json`源文件编写说明

Expand Down
2 changes: 1 addition & 1 deletion dist/cjs/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 40 additions & 2 deletions dist/cjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var import_utils = require("@umijs/utils");
var import_path = __toESM(require("path"));
var import_interface = require("./interface");
var import_utils2 = require("./utils");
var import_webpack = require("webpack");
var src_default = (api) => {
api.describe({
key: "browserExtension",
Expand Down Expand Up @@ -63,15 +64,16 @@ var src_default = (api) => {
// manifestHandler?: (manifestJson: any, target: Target) => any;
// joi2types bug 无法正确转换带参数的函数类型,因此只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest
// https://github.com/ycjcl868/joi2types/pull/17
manifestHandler: joi.any().description("Joi2types bug 无法正确转换带参数的函数类型,修复前只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest")
manifestHandler: joi.any().description("Joi2types bug 无法正确转换带参数的函数类型,修复前只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest"),
clearAbsPath: joi.alternatives([joi.boolean(), joi.string()]).default(true)
});
}
}
});
const isDev = api.env === "development";
let hasOpenHMR = false;
const pluginConfig = (0, import_utils2.initPluginConfig)(api.userConfig.browserExtension || {});
const { splitChunks, jsCssOutputDir, splitChunksPathName, contentScriptsPathName, backgroundPathName, targets, manifestHandler } = pluginConfig;
const { splitChunks, jsCssOutputDir, splitChunksPathName, contentScriptsPathName, backgroundPathName, targets, manifestHandler, clearAbsPath } = pluginConfig;
const manifestSourcePath = (0, import_utils2.completionManifestPath)(pluginConfig);
const manifestSourcePathBefore = manifestSourcePath.replace(/\.json$/, "");
let manifestBaseJson = (0, import_utils2.loadManifestBaseJson)(manifestSourcePath, pluginConfig);
Expand Down Expand Up @@ -151,6 +153,42 @@ var src_default = (api) => {
}
return !(!hasOpenHMR && plugin.constructor.name === "HotModuleReplacementPlugin");
});
if (clearAbsPath) {
memo.plugins.push((compiler) => {
compiler.hooks.thisCompilation.tap("ReplaceAbsolutePathPlugin", (compilation) => {
compilation.hooks.processAssets.tap(
{
name: "ReplaceAbsolutePathPlugin",
stage: import_webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE
},
(assets) => {
for (const assetName in assets) {
if (assetName.endsWith(".js")) {
const asset = assets[assetName];
let source = asset.source();
if (typeof source === "string" && source.includes(import_interface.ClearAbsPathKey)) {
const end = source.indexOf(import_interface.ClearAbsPathKey);
let start = end;
while (start > 0 && source[start] !== " ") {
start--;
}
if (start !== end) {
const absPath = source.slice(start + 1, end);
if (absPath) {
source = source.replace(new RegExp(absPath, "g"), typeof clearAbsPath === "string" && clearAbsPath ? clearAbsPath : "__ROOT__");
const newAssets = new import_webpack.sources.RawSource(source);
compilation.updateAsset(assetName, newAssets);
import_utils.logger.debug(`${import_interface.PluginName}[${assetName}] complete clear abs path: ${absPath}`);
}
}
}
}
}
}
);
});
});
}
}
if (enableSplitChunks) {
const backgroundEntry = (_a = Object.values(pagesConfig).find((config) => config.type === "background")) == null ? void 0 : _a.entry;
Expand Down
2 changes: 2 additions & 0 deletions dist/cjs/interface.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export declare const PluginName = "[umi-browser-extension]";
export declare const ClearAbsPathKey = "_node_modules_babel_runtime_helpers_";
export declare const F_EXCLUDE_COMPONENTS: string;
export declare const F_EXCLUDE_MODELS: string;
export declare const F_EXCLUDE_UTILS: string;
Expand All @@ -25,6 +26,7 @@ export interface browserExtensionConfig {
splitChunksPathName: string;
targets: Target[];
manifestHandler?: (manifestJson: any, target: Target) => any;
clearAbsPath: boolean | string;
}
export declare const browserExtensionDefaultConfig: browserExtensionConfig;
export interface browserExtensionEntryConfig {
Expand Down
2 changes: 1 addition & 1 deletion dist/cjs/interface.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion dist/cjs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
// src/interface.ts
var interface_exports = {};
__export(interface_exports, {
ClearAbsPathKey: () => ClearAbsPathKey,
F_EXCLUDE_COMPONENTS: () => F_EXCLUDE_COMPONENTS,
F_EXCLUDE_MODELS: () => F_EXCLUDE_MODELS,
F_EXCLUDE_UTILS: () => F_EXCLUDE_UTILS,
Expand All @@ -38,6 +39,7 @@ __export(interface_exports, {
module.exports = __toCommonJS(interface_exports);
var import_path = __toESM(require("path"));
var PluginName = "[umi-browser-extension]";
var ClearAbsPathKey = "_node_modules_babel_runtime_helpers_";
var F_EXCLUDE_COMPONENTS = `${import_path.default.posix.sep}components${import_path.default.posix.sep}`;
var F_EXCLUDE_MODELS = `${import_path.default.posix.sep}models${import_path.default.posix.sep}`;
var F_EXCLUDE_UTILS = `${import_path.default.posix.sep}utils${import_path.default.posix.sep}`;
Expand All @@ -58,10 +60,12 @@ var browserExtensionDefaultConfig = {
popupDefaultIcon: {},
splitChunks: true,
splitChunksPathName: "chunks",
targets: ["chrome"]
targets: ["chrome"],
clearAbsPath: true
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ClearAbsPathKey,
F_EXCLUDE_COMPONENTS,
F_EXCLUDE_MODELS,
F_EXCLUDE_UTILS,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"homepage": "https://github.com/kukushouhou/umi-plugin-browser-extension",
"description": "UmiJs v4 plugin: browser extension development",
"author": "Kukushouhou <1@kukushouhou.com>",
"version": "1.1.3",
"version": "1.1.4",
"main": "dist/cjs/index.js",
"types": "dist/cjs/index.d.ts",
"scripts": {
Expand Down
47 changes: 43 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type {IApi} from 'umi';
import {logger} from "@umijs/utils";
import Path from "path";
import {browserExtensionDefaultConfig, browserExtensionEntryConfig, PluginName} from "./interface";
import {browserExtensionDefaultConfig, browserExtensionEntryConfig, ClearAbsPathKey, PluginName} from "./interface";
import {completionManifestPath, completionWebpackEntryConfig, findPagesConfig, firstWriteAllFile, initPluginConfig, loadManifestBaseJson, loadManifestTargetJson, removeFileOrDirSync, splitChunksFilter, syncTargetsFiles, writeManifestV3Json} from "./utils";
import {Compilation, sources} from 'webpack';


export default (api: IApi) => {
Expand Down Expand Up @@ -32,7 +33,8 @@ export default (api: IApi) => {
// manifestHandler?: (manifestJson: any, target: Target) => any;
// joi2types bug 无法正确转换带参数的函数类型,因此只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest
// https://github.com/ycjcl868/joi2types/pull/17
manifestHandler: joi.any().description("Joi2types bug 无法正确转换带参数的函数类型,修复前只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest")
manifestHandler: joi.any().description("Joi2types bug 无法正确转换带参数的函数类型,修复前只能用any代替,实际需要传入(manifest: any, target?: Target) => manifest"),
clearAbsPath: joi.alternatives([joi.boolean(), joi.string()]).default(true),
});
},
}
Expand All @@ -41,7 +43,7 @@ export default (api: IApi) => {
const isDev = api.env === 'development';
let hasOpenHMR = false;
const pluginConfig = initPluginConfig(api.userConfig.browserExtension || {});
const {splitChunks, jsCssOutputDir, splitChunksPathName, contentScriptsPathName, backgroundPathName, targets, manifestHandler} = pluginConfig;
const {splitChunks, jsCssOutputDir, splitChunksPathName, contentScriptsPathName, backgroundPathName, targets, manifestHandler, clearAbsPath} = pluginConfig;
const manifestSourcePath = completionManifestPath(pluginConfig);
const manifestSourcePathBefore = manifestSourcePath.replace(/\.json$/, "");
let manifestBaseJson = loadManifestBaseJson(manifestSourcePath, pluginConfig);
Expand Down Expand Up @@ -142,6 +144,43 @@ export default (api: IApi) => {
// 同时也要移除热更新插件
return !(!hasOpenHMR && plugin.constructor.name === 'HotModuleReplacementPlugin');
});

if (clearAbsPath) {
memo.plugins.push((compiler) => {
compiler.hooks.thisCompilation.tap('ReplaceAbsolutePathPlugin', (compilation) => {
compilation.hooks.processAssets.tap(
{
name: 'ReplaceAbsolutePathPlugin',
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
},
(assets) => {
for (const assetName in assets) {
if (assetName.endsWith('.js')) {
const asset = assets[assetName];
let source = asset.source();
if (typeof source === "string" && source.includes(ClearAbsPathKey)) {
const end = source.indexOf(ClearAbsPathKey);
let start = end;
while (start > 0 && source[start] !== ' ') {
start--;
}
if (start !== end) {
const absPath = source.slice(start + 1, end);
if (absPath) {
source = source.replace(new RegExp(absPath, 'g'), typeof clearAbsPath === "string" && clearAbsPath ? clearAbsPath : '__ROOT__');
const newAssets = new sources.RawSource(source);
compilation.updateAsset(assetName, newAssets as any);
logger.debug(`${PluginName}[${assetName}] complete clear abs path: ${absPath}`);
}
}
}
}
}
}
);
});
});
}
}
if (enableSplitChunks) {
const backgroundEntry = Object.values(pagesConfig).find(config => config.type === 'background')?.entry;
Expand Down Expand Up @@ -174,10 +213,10 @@ export default (api: IApi) => {
}
}
// console.log("modifyWebpackConfig", memo);
// debugger;
return memo;
});


api.onBuildComplete(({err, stats}) => {
if (err) return;
firstWriteAllFile(stats, manifestBaseJson, manifestTargetsJson, outputPath, outputBasePath, pagesConfig, vendorEntry, targets, manifestHandler);
Expand Down
4 changes: 4 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Path from "path";

export const PluginName = "[umi-browser-extension]";

export const ClearAbsPathKey = "_node_modules_babel_runtime_helpers_";

// 排除组件文件夹名
export const F_EXCLUDE_COMPONENTS = `${Path.posix.sep}components${Path.posix.sep}`;
export const F_EXCLUDE_MODELS = `${Path.posix.sep}models${Path.posix.sep}`;
Expand Down Expand Up @@ -30,6 +32,7 @@ export interface browserExtensionConfig {
splitChunksPathName: string;
targets: Target[];
manifestHandler?: (manifestJson: any, target: Target) => any;
clearAbsPath: boolean | string;
}

export const browserExtensionDefaultConfig: browserExtensionConfig = {
Expand All @@ -50,6 +53,7 @@ export const browserExtensionDefaultConfig: browserExtensionConfig = {
splitChunks: true,
splitChunksPathName: "chunks",
targets: ['chrome'],
clearAbsPath: true,
};

export interface browserExtensionEntryConfig {
Expand Down

0 comments on commit 4541ee4

Please sign in to comment.