uniapp-async-pkg-inject
v0.1.0
Published
async pkg inject to already uniapp bundle
Downloads
3
Maintainers
Readme
how to use
first install the dependencies:
npm install uniapp-async-pkg-inject -D
use example:
write a webpack-plugin:
const { rewrite_dist_app_json, inject_empty_wrapper, traverse_all_components_json, traverse_some_components_json } = require('uniapp-async-pkg-inject/index');
class AutoInjectFuviewPackageDev {
constructor() {
this.isInject = false;
}
apply(compiler) {
const base_path = process.cwd();
const mode = process.env.NODE_ENV === 'production' ? 'build' : 'dev';
const distPath = path.join(base_path, `/dist/${mode}/mp-weixin`);
const appJsonPath = path.join(base_path, `/src/pages.json`);
// 需要忽略的路径,注意执行时会把这些装换成一个全局匹配的正则,所以你需要确保路径不会被误伤
const ignoreKeywords = ["app.json", "ext.json", "static", "node-modules", "uni_modules", "common"];
// 呃,这个属实是语言不同的无奈,用于存储需要异步化分包的名字
let asyncPkgRoots = [];
// 二次编译时拿到差量
const needed = []
// 是否需要重写app.json
let containAppJson = false;
compiler.hooks.assetEmitted.tap("collect change data", (fileName, content) => {
if (this.isInject) {
if (fileName.endsWith(".json")) {
// 如果有改动过`pages.json`,这里就需要重写一次`pages.json`
// 理论上不需要重新处理整个包的json,因为如果改pages.json,那一定会触发对应目标页面的json改变
// 不然就是uniapp的bug了,所以这里直接重写app.json并且拿差量的处理即可
if (fileName.includes('pages.json')) {
containAppJson = true
}
try {
needed.push([fileName, JSON.parse(content.toString())]);
} catch (error) {
console.error('someting went wrong when parse content')
}
}
}
})
compiler.hooks.done.tap("inject async pkg after emit assets", (compilation, callback) => {
if (!this.isInject) {
this.isInject = true;
// 重写`app.json`
asyncPkgRoots = rewrite_dist_app_json(distPath, appJsonPath);
// 注入占位组件(这一步也可以不要,不过你要自行调整逻辑,让占位变成你想要的)
inject_empty_wrapper(distPath);
// 遍历`dist/dev/mp-weixin`下非ignore的所有组件json
traverse_all_components_json(distPath, asyncPkgRoots, ignoreKeywords);
}
// 除了第一次之外,剩下的直接处理差量的即可
if (needed.length > 0) {
if (containAppJson) {
asyncPkgRoots = rewrite_dist_app_json(distPath, appJsonPath);
}
// 只处理差量的文件
traverse_some_components_json(distPath, needed, asyncPkgRoots, ignoreKeywords);
// needed = []
needed.splice(0, needed.length);
} else {
console.log("------------本次改动不包含组件引用改动------------")
}
containAppJson = false;
callback && callback()
})
}
}
and then add to your vue.config.js
:
plugins.push(
process.env.NODE_ENV === 'production' ?
new AutoInjectFuviewPackageProd() :
new AutoInjectFuviewPackageDev()
);