1.問題描述
我vue-cli寫了專案,介面都是用element-ui寫的,打包時報錯:
ERROR in assets/js/0.498ce690b229694d8858.js from UglifyJs
Unexpected token: operator (>) [./~/element-ui/src/mixins/emitter.js:2,0][assets/js/0.498ce690b229694d8858.js:3947,32]
2.問題理解
我理解了一下報錯資訊:
報錯說有一個錯誤在打包後的檔案中:assets/js/0.498ce690b229694d8858.js
,
錯誤的原因是:Unexpected token: operator (>)
,即:不能識別操作符(”>”大於號)
原始檔出錯地方是:element-ui/src/mixins/emitter.js
第2
行第0
列
打包檔案出錯地方:assets/js/0.498ce690b229694d8858.js
第3947
行第32
列
於是我找到兩個檔案出錯的程式碼一看,發現程式碼是一樣的!
//element-ui/src/mixins/emitter.js
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {//第2行
var name = child.$options.componentName;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
//assets/js/0.498ce690b229694d8858.js :
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {//第3947行,第32列是“=”
var name = child.$options.componentName;
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params));
} else {
broadcast.apply(child, [componentName, eventName].concat([params]));
}
});
}
this.$children.forEach(child => {});
中的=>
是es6的語法。但是現在很多瀏覽器不完成支援es6語法,所以才需要在打包過程中轉換成es5語法。
assets/js/0.498ce690b229694d8858.js
是打包的結果,這個檔案是會放在瀏覽器執行的,如果瀏覽器不支援es6語法,那程式碼就會出錯。
所以npm run build
報出錯誤資訊,也是合理的,如果你不理會這個報錯資訊,把程式碼拿取瀏覽器執行,就會出錯。
3.解決案例:vue-select
於是我很清楚,需要找到一種辦法,能夠把原始檔的es6語法的程式碼轉換成es5語法的程式碼。最後我找到了vue-select的一個issue討論是比較有幫助的:https://github.com/sagalbot/v…
This is a bug (#57, #69) that will be fixed in the next release – essentially babel doesn`t get applied to the mixins in src/mixins/, so they are not transpiled to ES5. The next release will be precompiled so that dev`s don`t have to modify the build process.
What`s your build process? If you are using webpack, you can configure babel-loader to run >on the files.
{
test: /.js$/, loader: `babel`, include: [ projectRoot + `/src`, projectRoot + `/test`, projectRoot + `/node_modules/vue-select` ]
}
I`m using the latest webpack template for vue-cli. In case anyone else wants to know >exactly where I put that, I updated the webpack.base.config.js file, this way:
{
test: /.js$/, loader: `babel`, include: [ path.resolve(__dirname, `../config`), path.resolve(__dirname, `../build`), path.resolve(__dirname, `../src`), path.resolve(__dirname, `../node_modules/vue-select`), ]
}
原文大概意思是:在一個專案中依賴了vue-select庫,打包時會報錯:Unexpected token punc «(», expected punc «:»
,原因是babel沒有把node_modules/vue-select目錄下的js檔案轉換成es5語法。於是就配置了一下,就解決了。
3.參考解決自己的問題
我在自己專案中的webpack.base.conf.js
找到了類似的地方,並加入配置:
//webpack.base.conf.js:
var path = require(`path`)
var utils = require(`./utils`)
var config = require(`../config`)
var vueLoaderConfig = require(`./vue-loader.conf`)
function resolve (dir) {
return path.join(__dirname, `..`, dir)
}
module.exports = {
entry: {
app: `./src/main.js`
},
output: {
path: config.build.assetsRoot,
filename: `[name].js`,
publicPath: process.env.NODE_ENV === `production`
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: [`.js`, `.vue`, `.json`],
alias: {
`vue$`: `vue/dist/vue.esm.js`,
`@`: resolve(`src`)
}
},
module: {
rules: [
{
test: /.vue$/,
loader: `vue-loader`,
options: vueLoaderConfig
},
{
test: /.js$/,
loader: `babel-loader`,
include: [
resolve(`src`),
resolve(`test`),
resolve(`node_modules/element-ui/src/mixins/emitter.js`),//<------add
]
},
{
test: /.(png|jpe?g|gif|svg)(?.*)?$/,
loader: `url-loader`,
options: {
limit: 10000,
name: utils.assetsPath(`img/[name].[hash:7].[ext]`)
}
},
{
test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
loader: `url-loader`,
options: {
limit: 10000,
name: utils.assetsPath(`fonts/[name].[hash:7].[ext]`)
}
}
]
}
}
如果您的vue-cli專案或webpack專案也遇到類似的錯誤,可以試試這樣解決。
感慨一下:
瞭解問題的本質比知道問題的答案重要
遇到問題需要抽絲剝繭地逐層分析