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 文件。查看 webpack 上 babel-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...