在使用webpack+vue开发时,一般使用vue-loader对.vue文件进行处理。
// webpack.config.js
// ...
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.export = {
//...
module:{
rules: [
// ...
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
]
}
vue-loader加载器可以解析处理vue单文件组件(SFC)。
它可以将vue组件解析的每个部分使用对应的loader,例如sytle标签使用sass,template标签使用pub。
具体过程:
通过编译器,将vue中template、script、style标签中的内容提取,转化为导入导出的方式,用type参数区分使用的loader
// source.vue会被处理为:
// import the <template> block
import render from 'source.vue?vue&type=template'
// import the <script> block
import script from 'source.vue?vue&type=script'
export * from 'source.vue?vue&type=script'
// import <style> blocks
import 'source.vue?vue&type=style&index=1'
script.render = render
export default script
VueLoaderPlugin插件会克隆webpack中的rules,并根据type
去执行对应的rules。例如:
// webpack中配置了babel-loader
// import script from 'source.vue?vue&type=script'
// 会被扩展为:
import script from 'babel-loader!vue-loader!source.vue?vue&type=script'
它还提供vue的HMR热替换功能。(需要webpack开启HMR)
根据上面的介绍,vue-loader会使用插件拷贝rules中的规则,然后对从.vue文件提取的js文件使用响应的js rule。
于是我在项目中使用了下面的rule
{
test: '/\.js$/',
exclude: /node_modules/,
use: [
'babel-loader',
'eslint-loader'
]
},
{
test: /\.vue$/,
use: [
'vue-loader',
]
}
理论上eslint-loader应该可以校验vue-loader处理vue文件获得的js代码。
但是结果并没有。又采取了以下方案:
去掉exclude(虽然babel编译报错,但eslint还是没有校验)
为eslint-loader单独写一个rule,依然无效(代码中exclude和enforce写不写都无效)
{
test: /\.js$/,
use: [
'eslint-loader',
],
// exclude: /node_modules/,
// enforce: 'pre',
},
最终没有找到原因,老老实实的给vue匹配加了个rule
{
test: /\.(js|vue)$/,
use: [
'eslint-loader',
],
enforce: 'pre' // 保证编译前执行
},
VueLoaderPlugin插件的源码中,选择性的忽略了eslint-loader。。。。。。。。。。。。。。。。
const dedupeESLintLoader = loaders => {
const res = []
let seen = false
loaders.forEach(l => {
if (!isESLintLoader(l)) {
res.push(l)
} else if (!seen) {
seen = true
res.push(l)
}
})
return res
}