Skip to content

vue cli 3 填坑记录 #14

@chenwangji

Description

@chenwangji

vue cli3 正式发布已经过去很久,甚至 vue-cli@4 也已经可以在官方仓库看到。

版本3 配置方式和之前版本差别巨大,需要踩过很多坑才能熟悉它的配置套路。

以下是一些踩坑的记录。

问题一:vue + ts 模版不会将 .js 通过 babel 转译

问题发现

项目一开始是通过命令行选择 vue + ts 生成。但是由于一些原因,我们部分文件还是沿用 js 来写。

当跑在比较旧的手机上时,检测到有报错,分析报错信息是因为 es6 扩展运算符导致的。让人比较诧异的是,这个配置下,vue cli 并没有默认去编译 js 代码。

这种情况下,检查 vue-cli 的默认配置就显得很有必要了。

我们可以通过执行在 package.json 的 script 上增加一个命令:

"scripts": {
    "inspect": "vue-cli-service inspect > output.js"
  },

这样,vue-cli3 的默认配置就可以导出到 output.js 中:

/* 省略其他 */

  /* config.module.rule('ts') */
  {
    test: /\.ts$/,
    use: [
      {
        loader: 'cache-loader',
        options: {
          cacheDirectory: '/Users/chenwangji/Desktop/work/project_work/ScratchBlockly/node_modules/.cache/ts-loader',
          cacheIdentifier: '48924560'
        }
      },
      {
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          appendTsSuffixTo: [
            '\\.vue$'
          ],
          happyPackMode: false
        }
      }
    ]
  },
  /* config.module.rule('tsx') */
  {
    test: /\.tsx$/,
    use: [
      {
        loader: 'cache-loader',
        options: {
          cacheDirectory: '/Users/chenwangji/Desktop/work/project_work/ScratchBlockly/node_modules/.cache/ts-loader',
          cacheIdentifier: '48924560'
        }
      },
      {
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          happyPackMode: false,
          appendTsxSuffixTo: [
            '\\.vue$'
          ]
        }
      }
    ]
  }

果然,这个配置下只会对 .ts, .tsx, .vue 文件执行 ts-loader 的编译(ts-loader 会内部会经过 babel 编译)。

所以我们需要手动增加对 .js 的编译支持。

解决方法

我们可以通过配置 babel-loader 来编译 js 文件。查看 webpackbabel-loader 的配置,我们需要完成以下配置:

module: {
  rules: [
    {
      test: /\.m?js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}

所以我们需要运行以下命令安装依赖:

yarn add -D babel-loader @babel/core @babel/preset-env

我们知道可以通过 vue.config.js 去修改 webpack 的配置,不过 vue-cli 3 配置方式改为了通过 webpack-chain,配置起来既麻烦又很不清晰(难道是为了不让别人轻易去修改默认配置吗?),不过大体可以通过 vue-cil 官网去了解配置。

所以以上配置配置在 vue.config.js 中的配置如下:

chainWebpack: config => {
    config.module
        .rule("js")
        .test(/\.m?jsx?$/)
        .exclude
        .add(filepath => {
            return /node_modules/.test(filepath)
        })
        .end()
        .use('babel-loader')
        .loader(require.resolve('babel-loader'))
        .tap(() => Object.assign({}, { presets: [
            '@babel/preset-env',
        ] }))
}

配置之后再执行构建,项目中的 .js 代码成功编译,老旧手机浏览器报错问题解决。

配置 webpack 生成可调试的代码

问题发现

开发模式下 .vue 文件编译后是这样的:

/* hot reload */
if (module.hot) {
  var api = require("/Users/chenwangji/Desktop/work/project_work/ScratchBlockly/node_modules/vue-hot-reload-api/dist/index.js")
  api.install(require('vue'))
  if (api.compatible) {
    module.hot.accept()
    if (!module.hot.data) {
      api.createRecord('656621cd', component.options)
    } else {
      api.reload('656621cd', component.options)
    }
    module.hot.accept("./Index.vue?vue&type=template&id=656621cd&", function () {
      api.rerender('656621cd', {
        render: render,
        staticRenderFns: staticRenderFns
      })
    })
  }
}
component.options.__file = "src/coding/views/editor/Index.vue"
export default component.exports

文件目录是这样的:

文件目录

这其实也不是问题,应该是 feature, 但是这个 feature 让我们开发调试极其困难,所以我们需要让开发环境文件按照原来的目录去生成。

解决方法

通过查阅文档,我们可以通过以下方式配置:

configureWebpack: config => {
    // 根据环境变量修改打包文件名
    const production = process.env.NODE_ENV === 'production'
    if (!production) {
        config.output.devtoolModuleFilenameTemplate = info => {
            const resPath = info.resourcePath
            if ((/\.vue$/.test(resPath) && !/type=script/.test(info.identifier)) || /node_modules/.test(resPath)) 
            {
                return `webpack:///${resPath}?${info.hash}`
            }
            return `webpack:///${resPath.replace('./src', 'uncompiled-code/src')}`
        }
    }
}

这样就可以达到我们想要的效果,调试起来就会方便很多。

禁止图片转为 base64

问题发现

由于某个库不支持 base64 的图片,所以需要配置让图片全部不转 base64。

解决方法

需要更改 url-loader 配置。

// 图片不转 base64
chainWebpack: config => {
    config.module
        .rule('images')
        .use('url-loader')
        .loader('url-loader')
        .tap(options => Object.assign(options, {limit: 1})) // 这里 limit 如果配置为 0 反而是会把所谓图片转为 base64,所以配置为 1
},

To be continued...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions