萤火钱包谷歌浏览器插件版(1): vue-cli2升级vue-cli3

352 阅读4分钟

先放github地址github.com/imloama/fir…,代码比较渣,一直想重构,还未重构,考虑等着vue3出了后,跟着用typescript重构一遍(基于vue2的重构版本写了个开头,有点难产了)。这是一个区块链电子钱包,主要用于恒星区块链的代币管理。

这个项目从一开始的vue+cordova的hybrid应用firefly,到vue+electron构造桌面应用desktop-client,再到考虑完成谷歌浏览器插件版。大部分代码是一样的,采用vue+vuex+vue-router+vuetify写的,采用webpack打包适配到不同的平台,基于不同的平台,有些特殊的功能代码。

进化到谷歌浏览器插件版,因为vue-cli3已经出了一段时间了,本着学习的态度,尝试进行迁移适配,感觉困难重重,很不适应,经历磨难,总算是见到曙光了。

从webpack3到webpack4

在vue-cli2时代,主要是使用webpack的配置文件进行处理的,项目中基本上都能见到webpack.xx.config.js类似的文件,从package.json的scripts执行中就可以看到。

到了vue-cli3时代,默认的webpack文件不见了,而是基于webpack-mergewebpack-chain进行了扩展,可以自定义vue.config.js,从而实现自定义的功能。

在webpack4之后,也是吸收了rollup等后起之秀的经验,实现了零配置化,即可以通过webpack --命令行的形式,完成配置,同时也支持通过config.js文件进行配置。

为了实现一些自定义的打包需求,就需要修改默认的打包过程,这时,就需要在根目录上创建vue.config.js文件,通过它来实现自定义的打包。

vue.config.js参数

官方配置文件说明地址为cli.vuejs.org/zh/config

需要自定义的点说明

pages

多页面打包配置

module.exports = {
  pages: {
    index: {
      // page 的入口
      entry: 'src/index/main.js',
      // 模板来源
      template: 'public/index.html',
      // 在 dist/index.html 的输出
      filename: 'index.html',
      // 当使用 title 选项时,
      // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
      title: 'Index Page',
      // 在这个页面中包含的块,默认情况下会包含
      // 提取出来的通用 chunk 和 vendor chunk, index对应着前边的key-index
      chunks: ['chunk-vendors', 'chunk-common', 'index']
    },
    // 当使用只有入口的字符串格式时,
    // 模板会被推导为 `public/subpage.html`
    // 并且如果找不到的话,就回退到 `public/index.html`。
    // 输出文件名会被推导为 `subpage.html`。
    subpage: 'src/subpage/main.js'
  }
}

这部分,对于如果两个页面都引用了某个组件,组件中使用了vuex,可能会有问题,我还在尝试。改造后的项目有问题,新建的工程暂时未发现问题。

productionSourceMap

返回true表示不生成sourcemap文件,sourcemap文件在开发时比较有用,主要是报错异常相对清晰,而生产中可以通过返回false取消掉,我是根据环境变量不同,返回了不同的结果,其中BUILDTYPE是我在执行npm run dev时传递的环境变量

productionSourceMap:  process.env.BUILDTYPE === 'dev',

configureWebpack

配置webpack,目前我主要用到了chainWebpack

chainWebpack

由于谷歌浏览器插件需要一个后台js和content-script等js文件,所以需要配置webpack生成多个js,但生成的html只有一个,从而配置pages就不太合适,按照webpack.config.js中的配置,即设置entry,实质上,pages也是生成了entry,所以添加了多个entrys配置,

 config
        .entry('index')
        .add(resolve('src')+'/main.js')
        .end()
        .entry('background')
        .add(resolve('src')+'/background.js')
        .end()
        .entry('chromereload')
        .add(resolve('src')+'/chromereload.js')
        .end()
        .output
        .filename('js/[name].js');

默认情况下,生成HTML是使用html-webpack-plugin完成的,由于我取消了pages的值,所以我也删除了添加的html-webpack-plugin插件,而是改用自定义的引用html-webpack-plugin,同时,取消了preload和prefetch,因为使用谷歌浏览器,主要是引用本地文件,没有网络请求,这点优化可以不做。 自定义引用html-webpack-plugin,可以配置excludeChunks表示哪些entry中的Js不会被包含,或者也可以使用chunks,表示引用哪些js,效果是相同的

config.plugins.delete('html')
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')
    
 config.plugin('html')
        .use(new HtmlWebpackPlugin({
            excludeChunks: ['background','chromereload','ffw','ffwmain'],
            // chunks:['chunk-vendors','chunk-common','index'],
            template: 'public/index.html',
            filename: 'index.html'
        }));

添加了copy-webpack-plugin,来完成一些静态文件的复制

config.plugin('CopyWebpackPlugin')
        .use(new CopyWebpackPlugin([
            {
              from: 'src/manifest.json',
              to: 'manifest.json',
              transform: (content) => {
                const jsonContent = JSON.parse(content);
                jsonContent.version = version;
                if (config.mode === 'development') {
                  jsonContent['content_security_policy'] = "script-src 'self' 'unsafe-eval'; object-src 'self'";
                }
                return JSON.stringify(jsonContent, null, 2);
              },
            },
            {from:'src/_locales', to: '_locales'},
            {from:'src/icons', to: 'icons'}
          ])
      );

vue-cli-service服务

vue-cli-service serve

启动一个开发服务器,支持热重载,直接通过浏览器访问,但由于我需要做一个谷歌浏览器插件,无法通过谷歌浏览器的扩展程序进行加载

vue-cli-service build

打包服务,生成的文件可以通过谷歌浏览器的扩展程序进行加载,完成测试。 在测试情况下,只需要webpack打包,不需要对js进行混淆等处理,所以需要取消混淆的功能,这个需要改动vue.config.js中的chainWebpack部分

 chainWebpack: (config)=>{
        let isdev = process.env.BUILDTYPE === 'dev'//dev表示为开发模式
        if(isdev){
            config.optimization.minimize(false);
        }
    }

目前还在和vue-cli3奋斗中。