babel-loader 编译node_module 报错
问题
在vue的webpack模板项目中,我把 node_module目录 include 给 babel-loader 对引用到的模块进行es6 -> es5 转译,结果npm run build
的时候出现了 警告和错误,错误和警告都比较多且重复,我下面展示几个不同的错误区域截图。
我为了解决这个问题开了一个github项目,项目很小,安装完依赖就可以build复现错误。
https://github.com/Yatoo2018/...
错误截图
babelrc内容
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
这是webpack的配置:
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
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/webpack-dev-server/client')], // 原先配置是这个
include: [resolve('src'), resolve('test'), resolve('node_modules')] // 我把node_moudle加进去了,然后就出现了我的问题
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
之所以添加node_module目录这个配置给babel-loader去转换语法,是因为
我在项目中引用了一个swiper,通过 import Swiper from "swiper"
这样的ES6的方式引入了swiper,且按照swiper官网的提示,需要添加babel-loader的exclude配置。
我们先看下这个exclude配置的正则排除了什么样的文件路径:
这个 /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/
这个正则匹配了只要字符串中包含node_modules目录下的dom7,ssr-window和swiper就不匹配,其他的都匹配。
而这个正则放在exclude的配置下,那么就说明它的含义是要把其他node_module中的模块都从babel-loader的转义中排除掉,没有排除上面那三个module。
所以问题1 一般来想,开发这些库的人应该会比我考虑的更严谨一些,所以我就很奇怪:要明确对这三个模块进行语法转义不应该是将其添加到include配置吗, 为啥要绕一下,反过来排除其他的而留下他们三个,就不担心这样的配置被添加到项目中,本来想要被babel-loader转义的模块,结果被你swiper给的配置给排除了,出现问题?
先让我们把上面疑问略过,我根据swiper给的webpack配置把babel-loader的rule配置调整如下:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
include: [resolve('src'), resolve('test'),resolve('node_modules/webpack-dev-server/client')]
},
但是编译的 vender.hashxxxxx.js 中还是能看到
问题2:这个文件中仍然存在dom7模块的const 声明的变量,并没有转换?
好吧,猜测这个方式存在问题,于是我想 既然要明确的把这三个模块进行转义,那么我就include这三个模块给babel-loader
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'),resolve('node_modules/webpack-dev-server/client'),resolve('node_modules/swiper'),resolve('node_modules/dom7'),resolve('node_modules/ssr-window')]
},
编译后的文件信息:
这样做了之后,npm run build之后语法都转换完成了,也正常了。至此swiper引入的问题应该解决了,但是项目中还有一些其他的类似swiper这样的module, 要把他们一个个摘出来include一下也是可行的,稍微麻烦了一点。所以既然是这样,那么我何不将 node_module目录 include给babel-loader,这样做的话,babel-loader应该就能转义被项目引用到的任何文件(也就是node_module中那些直接或者间接被依赖的module),而我也期待任何可能用es6语法写的模块都会被babel转一下。
于是,我调整配置
{
test: /\.js$/,
loader: 'babel-loader',
//exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
include: [resolve('src'), resolve('test'),resolve('node_modules/webpack-dev-server/client'),resolve('node_modules')]
// include: [resolve('src'), resolve('test'),resolve('node_modules/webpack-dev-server/client'),resolve('node_modules/swiper'),resolve('node_modules/dom7'),resolve('node_modules/ssr-window')]
}
但是当我这么做了,结果却出现了很多错误,如上面截图部分的错误。
所以 问题3 当我把node_module给了babel-loader去转译,事实上我的目的达到了,文件确实都被babel转成功了,但是 为什么会出现很多上述警告和错误?
这时候编译后的文件信息:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一个问题:
代表匹配后面不是
dom7|ssr-window|swiper
这3个的规则,也就是说如果你import
了这个3个都会被babel
处理,因为这三个都是支持esm
的语法。第二个问题:
这种写法你并没有
include(dom7|ssr-window|swiper)
,所以自然不会babel
处理,exclude
主要是进行排除法。第三个问题:
你将所有的
node_modules include
进来,这就可能有些模块没有esm
的语法,比如babel-runtime
,lodash
等,就可能导致报错或者警告。