uniapp小程序迁移到TS (6)

这次产生了实际效果,确实能做到按需引入了,我高兴地进行编译,编译通过了,然后打开微信开发者工具,发现报错了,然后发现那边json文件出现了一个错误,引入的组件未找到,在json文件里将引入的文件原封不动得放了进去,也就是shst-campus/index,这明显不是个组件,而且实际上大概率是因为使用的插件和原本的插件解析时间没有对上,uniapp的插件在前解析已经完成了,所以就很尴尬,我想着通过编写一个webpack插件去解决这个json的问题。

export class UniappLoadDemandWebpackPlugin { constructor(options) { this.options = options || {}; } apply(compiler) { compiler.hooks.emit.tapAsync("UniappLoadDemandWebpackPlugin", (compilation, done) => { Object.keys(compilation.assets).forEach(key => { if (/^\./.test(key)) return void 0; if (!/.*\.json$/.test(key)) return void 0; const root = "node-modules"; const asset = compilation.assets[key]; const target = JSON.parse(asset.source()); if (!target.usingComponents) return void 0; Object.keys(target.usingComponents).forEach(componentsKey => { const item = target.usingComponents[componentsKey]; if (item.indexOf("http://www.likecs.com/" + root + "http://www.likecs.com/" + this.options.libraryName) === 0) { target.usingComponents[ componentsKey ] = `/${root}/${this.options.libraryName}/${this.options.libDir}/${componentsKey}/index`; } }); compilation.assets[key] = { source() { return JSON.stringify(target); }, size() { return this.source().length; }, }; }); done(); }); } } /* // vue.config.js module.exports = { configureWebpack: { // ... plugins: [ // ... new UniappLoadDemandWebpackPlugin({ libraryName: "shst-campus", libDir: "src/components", }), // ... ], // ... }, }; */

通过这个插件,我确实成功解决了json文件的组件引入问题,然后启动微信开发者工具,然后发现组件成功加载了,但是逻辑与样式全部丢失了,在我奇怪的时候我去查看了组件的编译情况,发现了组件根本没有编译成功,js与css都编译失败了,这就尴尬了,实际上在编译过程中uniapp的插件并没有抛出任何异常,相关的情况都被他内部吃掉了,然后我依旧是想通过编写webpack插件的形式去解决这个问题,尝试在compiler、compilation钩子中处理都没有解决这个问题,之后在NormalModuleFactory这个Hook中打印了一下发现,通过babel-plugin-component的处理,在这里的source已经被指定为想要的路径了,但是在uniapp编译的时候还是有问题的,然后我就在想uniapp处理这个相关的东西到底是有多早,之后尝试JavascriptParser钩子也没有成功处理,好家伙估计是在babel解析的时候就已经完成了,实际上他确实也有一个插件@dcloudio/webpack-uni-mp-loader/lib/babel/util.js,这里边后边还有坑。之后我又回到了babel-plugin-import这个插件,因为这个插件是uniapp的依赖中携带的处理插件,所以理论上在里边是用过这个插件的,之后我注意到他在babel.config.js里有一个处理@dcloudio/uni-ui的语句。

process.UNI_LIBRARIES = process.UNI_LIBRARIES || ["@dcloudio/uni-ui"]; process.UNI_LIBRARIES.forEach(libraryName => { plugins.push([ "import", { libraryName: libraryName, customName: name => { return `${libraryName}/lib/${name}/${name}`; }, }, ]); });

那么我就想着我也写一个类似的,具体过程只是描述一下,首先之前我也是写了一个类似的声明,但是并没有生效,我尝试把自己的组件写到process.UNI_LIBRARIES然后发现竟然生效了,这让我很吃惊,想了想肯定是在process.UNI_LIBRARIES做了一些处理,然后我把这个稍微修改了一下,也就是在process.UNI_LIBRARIES中处理了以后也有babel-plugin-import插件处理,之后我启动了编译,发现依旧是那个问题,在那里边的文件无法成功编译,内容是空的,而且错误信息都被吃掉了,没有任何报错出来,好家伙要了命,而且他也影响到了@dcloudio/uni-ui的组件引用,这是我随便引用了一个组件发现的,这里边的组件也会变成空的,无法成功解析,并且在json文件中,对于我的文件的声明是src/components下的,他给我声明成了lib下的文件,然后我去看了看他的有一个babel的插件,里边有引用@dcloudio/webpack-uni-mp-loader/lib/babel/util.js,这里边的process.UNI_LIBRARIES的source处理是写死的,真的是要了亲命,所以要想处理好这个问题,必须提前处理vue文件的引用声明,因为直接写明src/components下的引用是没有问题的,而想在uniapp之前处理好这个问题,那么只能编写一个loader去处理了,我自行实现了一个正则去匹配import语句然后将import解析出来去处理完整的path。之后考虑到引用的复杂性,还是考虑去引用一个相对比较通用的解析库区实现import语句的解析而不只是通过正则表达式的匹配区完成这件事,然后使用parse-imports去完成这个loader。

const transform = str => str.replace(/\B([A-Z])/g, "-$1").toLowerCase(); module.exports = function (source) { const name = this.query.name; if (!name) return source; const path = this.query.path || "lib"; const main = this.query.main; return source.replace( // maybe use parse-imports to parse import statement new RegExp( `import[\\s]*?\\{[\\s]*?([\\s\\S]*?)[\\s]*?\\}[\\s]*?from[\\s]*?[""]${name}[""];?`, "g" ), function (_, $1) { let target = ""; $1.split(",").forEach(item => { const transformedComponentName = transform(item.split("as")[0].trim()); const single = `import { ${item} } from "${name}/${path}/${transformedComponentName}/${ main || transformedComponentName }";`; target = target + single; }); return target; } ); }; /* // vue.config.js module.exports = { transpileDependencies: ["shst-campus"], configureWebpack: { resolve: { alias: { "@": path.join(__dirname, "./src"), }, }, module: { rules: [ { test: /\.vue$/, loader: "shst-campus/build/components-loader", options: { name: "shst-campus", path: "src/components", main: "index", }, }, ], }, plugins: [], }, }; */ 构建新目录并发布

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjss.html