写点什么

vue2 升级 vue3:webpack vue-loader 打包配置

作者:zhoulujun
  • 2022 年 6 月 21 日
  • 本文字数:2837 字

    阅读完需:约 9 分钟

如果没有啥特别的需求还是推荐 vue-cli!


vite vue3 TSX 项目虽然 vite 很香,但是 vite rollup 动态加载,多页面 等问题比较难搞


vite 的缺点 wepback webpack_public_path 没有找到好的实践方案。


webpack_public_path = window.BK_STATIC_URL;第二个,动态加载 css 里面的资源


/**


  • @file 替换 asset css 中的 BK_STATIC_URL,webpack_public_path 没法解决 asset 里静态资源的 url

  • @author*/


const { extname } = require('path');


class ReplaceCSSStaticUrlPlugin {apply(compiler) {// emit: 在生成资源并输出到目录之前 compiler.hooks.emit.tapAsync('ReplaceCSSStaticUrlPlugin', (compilation, callback) => {const assets = Object.keys(compilation.assets);const assetsLen = assets.length;


  for (let i = 0; i < assetsLen; i++) {    const fileName = assets[i];    const name = extname(fileName);    if (extname(fileName) !== '.css') {      continue;    }    const asset = compilation.assets[fileName];    let minifyFileContent = asset.source().toString()      .replace(        /\{\{\s*BK_STATIC_URL\s*\}\}/g,        () => '../',      );    compilation.assets[fileName] = {      // 返回文件内容      source: () => minifyFileContent,      // 返回文件大小      size: () => Buffer.byteLength(minifyFileContent, 'utf8'),    };  }
callback();});
复制代码


}}module.exports = ReplaceCSSStaticUrlPlugin;


虽然有 vite-plugin-dynamic-publicpath 等插件,但是并不是非常好使


多页面配置,主要还是修改 rollup 配置


build: {assetsDir: 'assets', // 指定生成静态资源的存放路径 rollupOptions: {input: {admin: path.resolve(__dirname, 'src/index.html'),page: path.resolve(__dirname, 'src/page/index.html'),index: path.resolve(__dirname, 'src/index/index.html'),},output: {chunkFileNames: 'static/js/[name]-[hash].js',entryFileNames: 'static/js/[name]-[hash].js',assetFileNames: 'static/[ext]/[name]-[hash].[ext]',}},}多页面更多的资料,网上很多,这里推荐几篇文章:


vue+vite 多页应用配置及页面路径更改 https://juejin.cn/post/7004784113706090526


Vite 入门以及从 webpack 切换到 Vite 遇到的问题总结 https://jishuin.proginn.com/p/763bfbd4f55a


多页面貌似解决了,当 rollup 打包完成后,都在二级目录,虽然有办法解决,但是一路搞下来,不想在折腾了


想来想去还是 webpack 原有配置方便


webpack vue3 TSX 只需要升级 npm 包:vue-loader vue-template-compiler"


vue-loader:它是基于 webpack 的一个的 loader 插件,解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,再分别把它们交给对应的 loader 去处理如 style-loader 、 less-loader 等等,核心的作用,就是 提取 。


@vue/compiler-sfc: Vue 2.x 时代,需要 vue-template-compiler 插件处理 .vue 内容为 ast , Vue 3.x 则变成 @vue/compiler-sfc 。


vue-loader 需要注意之前的


import VueLoaderPlugin from 'vue-loader/lib/plugin';新的


import { VueLoaderPlugin } from 'vue-loader';VueLoaderPlugin 的职责是将你定义过的其它规则复制并应用到 .vue 文件里相应语言的块。例如,如果你有一条匹配 /.js$/ 的规则,那么它会应用到 .vue 文件里的 <script> 块。


转换 jsx 需要安装 https://github.com/vuejs/babel-plugin-jsx


关于 tsx,具体推荐阅读:重拳出击:打造 Vue3.0 + Typescript + TSX 开(乞)发(丐)模式 https://juejin.cn/post/6844904054103998477


module.exports = function({ types: t }) {const buildAttrsCall = (attribs, t) => {const props = []attribs.forEach(attr => {const name = attr.name.nameconst value = attr.value!t.isJSXExpressionContainer(value) &&props.push(t.objectProperty(t.stringLiteral(name), value))t.isJSXExpressionContainer(value) &&props.push(t.objectProperty(t.stringLiteral(name), value.expression))})


return t.ObjectExpression(props)
复制代码


}


const jsxVisitor = {JSXElement: {exit(path, state) {


// 获取 jsxconst openingPath = path.get("openingElement")const children = t.react.buildChildren(openingPath.parent)


    const tagNode = t.react.isCompatTag(openingPath.node.name.name)      ? t.stringLiteral(openingPath.node.name.name)      : t.identifier(openingPath.node.name.name)
// 创建 Vue h const createElement = t.identifier('h') const attrs = buildAttrsCall(openingPath.node.attributes, t) // 创建 h(tag,{...attrs}, [chidren]) const callExpr = t.callExpression(createElement, [tagNode, attrs, t.arrayExpression(children)]) path.replaceWith(t.inherits(callExpr, path.node)) }},JSXAttribute(path) { if (t.isJSXElement(path.node.value)) { path.node.value = t.jsxExpressionContainer(path.node.value); }},Program: { exit(path, state) {
const hasImportedVue = (path) => { return path.node.body.filter(p => p.type === 'ImportDeclaration').some(p => p.source.value == 'vue') } // 注入 h 函数 if (path.node.start === 0) { if (!hasImportedVue(path)) { path.node.body.unshift( t.importDeclaration( [t.ImportSpecifier(t.identifier('h'), t.identifier('h'))], t.stringLiteral('vue') ) ) } else { const vueSource = path.node.body .filter(p => p.type === 'ImportDeclaration') .find(p => p.source.value == 'vue') const key = vueSource.specifiers.map(s => s.imported.name) if (key.includes('h')) { } else { vueSource.specifiers.unshift(t.ImportSpecifier(t.identifier('h'), t.identifier('h'))) } } } }}
复制代码


}


return {visitor: jsxVisitor,inherits:() => {return {manipulateOptions(opts, parserOpts) {parserOpts.plugins.push("jsx")}}}}}这段时间做 bk-vision 项目,分别试过


vite


vue-cli


webpack


最后还是升级了 bkui-cli,vue2 升级 vue3,打包工具还是不要变为好。


https://github.com/zhoulujun/bkui-cli


参考文章:


Vue 3 和 Webpack 5 来了,手动搭建的知识该更新了 https://juejin.cn/post/6921161482663100423


打造 Vue3.0 + Typescript + TSX 开(乞)发(丐)模式 https://juejin.cn/post/6844904054103998477


转载本站文章《vue2 升级 vue3:webpack vue-loader 打包配置》,请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8852.html

用户头像

zhoulujun

关注

还未添加个人签名 2021.06.25 加入

还未添加个人简介

评论

发布
暂无评论
vue2升级vue3:webpack vue-loader 打包配置_vite_zhoulujun_InfoQ写作社区