我是一个标题党,这篇文章介绍一点babel的默认配置套路,总结了一点遇到的项目管理问题。javascript
_objectSpread is not defined
_objectSpread
就是使用了新的对象展开的语法...obj
,编译以后才出现的。固然这里我也调试了编译后打代码。【若是你想看编译打包后代码,介绍一篇文章给你: webpack编译vue项目生成的代码探索】git log
快速分析package.json
的变动,发现只更新过babel
相关。因此实锤是babel
问题。分析git log
时,咱们当时作的commit message style
统一的做用就发挥出来了,全部的工具链相关变动,统一都是chore
开头,因此才能作到快速定位。顺便看看咱们项目的commit message
css
场景重现:babel repl demo连接html
真实缘由:对象展开的语法,babel编译以后注入了
_objectSpread
或者_objectSpread2
函数来处理,维护的小伙伴没有把全部的分支都覆盖。修复这个issues的小伙伴也挺幽默,估计也是被折腾的够呛,说了一句玩笑话I'll now go hiding myself somewhere and I won't touch an helper for a few months 😆前端并且此bug是
babel v7.5.4
修复的,并且在低版本的@babel/core
使用了高版本的@babel/plugin-proposal-object-rest-spread
才能重现。vue
_objectSpread
官方issues相关连接:java
ReferenceError: _objectSpread is not defined after updatenode
Missing helpers only throw oncewebpack
Fix _objectSpread2 for realgit
找的问题的根源了,新问题来了,我怎么更新
@babel/core
呢?github由于不是项目直接依赖的
@babel/core
,而是其它工具依赖,我更新了也不必定起做用。
介绍npm
两个很是有用的命令:
查看项目中安装的package版本和依赖关系
npm ls @babel/core
`-- @vue/cli-plugin-babel@3.9.2
`-- @babel/core@7.5.4
复制代码
知道了依赖@babel/core是@vue/cli-plugin-babel
,那升级@vue/cli-plugin-babel
就好了。
查看npm
仓库的package版本和依赖
npm show @babel/core
复制代码
推荐一个npm-check
工具,专门用来更新依赖。
能够执行
npm-check -u
来进行交互式选择更新,并且还列出了官方文档,能够直接看看release log以后再决定是否更新。
babel
的plugin和preset配置默认套路原本我就比较懒,一直在计划学习的路上,基本都没落实行动。此次项目出现问题,我不得不去了解了一下,babel配置的那些套路。Babel的v7版本全部包都重命名了,因此仍是要作到了解。
包含的内容太多,仔细过一遍才行,不少配置或者包名称命名规则都修改了。
babel v7.4
支持core-js@3
babel v7.4支持core-js@3,尤为是对
@babel/polyfill
和@babel/preset-env
又带来了不少改变。
新的corejs
配置项
corejs配置项连接options corejs
当项目中的babel升级到v7.4+时会出现下面的警告:
WARNING: We noticed you're using the
useBuiltIns
option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via thecorejs
option.
// 使用core-js@3的babel.config.js
module.exports = function (api) {
api.cache(true);
const presets = [
["@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs":3, // 指定版本
"targets":{
"browsers":["> 1%", "last 2 versions", "not ie <= 8"]
}
}
]
];
return {
presets,
// plugins
};
}
复制代码
注意: 把相应的core-js安装到项目依赖中,npm i core-js@2
或者npm i core-js@3
@babel/polyfill
不支持从core-js2升级到core-js3,因此v7.4开始@babel/polyfill
变成过期(deprecated)
若是项目中使用core-js@3,则应该修改导入配置
import "@babel/polyfill";
复制代码
替换为:
import "core-js/stable";
import "regenerator-runtime/runtime";
复制代码
直接安装依赖到项目:
npm i --save core-js regenerator-runtime
复制代码
由于babel和core-js绑定的很紧密,因此推荐看一下core-js做者的文章:core-js-3-babel-and-a-look-into-the-future详细介绍了core-js@3版本带来的改变,以及解决的问题。
syntax plugins容许babel去parse特定的类型的syntax而不是去转换变形(transform)
注意:transform plugins会自动启用syntax plugins。 所以,若是已经使用了相应的transform plugins,则无需指定syntax plugins。
若是 plugin 在 npm 上,你能够传入预设名称,babel 将检查它是否已安装在 node_modules
中
{
"plugins": ["babel-plugin-myPlugin"]
}
复制代码
还能够指定的相对/绝对路径。
{
"plugins": ["./node_modules/asdf/plugin"]
}
复制代码
若是包的名称以 babel-plugin-
为前缀,可使用简写:
{
"plugins": [
"myPlugin",
"babel-plugin-myPlugin" // equivalent
]
}
复制代码
这也适用于 scoped 包:
{
"plugins": [
"@org/babel-plugin-name",
"@org/name" // equivalent
]
}
复制代码
若是两个transforms都访问“程序”节点,则transforms将以plugin或preset顺序运行。
- plugin在preset以前运行。
- plugin执行顺序是第一个到最后一个。
- preset顺序相反(从最后到第一个)。
{
"plugins": ["transform-decorators-legacy", "transform-class-properties"]
}
复制代码
先执行transform-decorators-legacy
后transform-class-properties
plugins和 presets 均可以经过将名称和选项对象放在配置中的数组中来指定选项。
对于不指定选项,这些都是等同的:
{
"plugins": ["pluginA", ["pluginA"], ["pluginA", {}]]
}
复制代码
要指定选项,请使用选项名称做为 key 传递对象。
{
"plugins": [
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}
复制代码
preset是一个插件数组
module.exports = function() {
return {
plugins: [
"pluginA",
"pluginB",
"pluginC",
]
};
}
复制代码
Presets 能够包含其余的 presets 以及带有选项的插件。
module.exports = () => ({
presets: [
require("@babel/preset-env"),
],
plugins: [
[require("@babel/plugin-proposal-class-properties"), { loose: true }],
require("@babel/plugin-proposal-object-rest-spread"),
],
});
复制代码
若是 preset 在 npm 上,你能够传入预设名称,babel 将检查它是否已安装在 node_modules
中
{
"presets": ["babel-preset-myPreset"]
}
复制代码
还能够指定 presets 的相对/绝对路径。
{
"presets": ["./myProject/myPreset"]
}
复制代码
若是包的名称以 babel-preset-
为前缀,可使用简写:
{
"presets": [
"myPreset",
"babel-preset-myPreset" // 等同
]
}
复制代码
这也适用于 scoped 包:
{
"presets": [
"@org/babel-preset-name",
"@org/name" // 等同
]
}
复制代码
// vue-cli生成的babel.config.js
module.exports = {
presets: [
[
'@vue/app', // 对应 @vue/babel-preset-app,当时害的我找来找去都没找到包
{
useBuiltIns: 'entry',
corejs: 2, // @see https://babeljs.io/docs/en/babel-preset-env#corejs
},
],
};
复制代码
Preset 的顺序是相反的(从最后一个到第一个).
{
"presets": [
"a",
"b",
"c"
]
}
复制代码
将会按照如下顺序运行:c
, b
, 而后 a
。
插件和 presets 均可以经过将名称和选项对象放在配置中的数组中来指定选项。
对于不指定选项,这些都是等同的:
{
"presets": [
"presetA",
["presetA"],
["presetA", {}],
]
}
复制代码
要指定选项,请使用选项名称做为 key 传递对象。
{
"presets": [
["@babel/preset-env", {
"loose": true,
"modules": false
}]
]
}
复制代码
ant-desgin-vue
的依赖加载配置:
module.exports = {
presets: [
[
'@vue/app',
{
useBuiltIns: 'entry',
corejs: 2, // @see https://babeljs.io/docs/en/babel-preset-env#corejs
},
],
],
plugins: [
[ // @see https://github.com/vueComponent/ant-design-vue/issues/193
'import', // babel-plugin-import
{ libraryName: 'ant-design-vue', libraryDirectory: 'es', style: true },
],
],
};
复制代码
前端的知识链太长,技术更新愈来愈快。前端的投资风险仍是很大,因此谨慎选择框架,分配一点时间投资在业界公认的工具上也是不错的,例如:webpack, babel, vs code, scss等。这些都是现代前端工程的构建工具,因此生命周期会比某一个框架更长远。
core-js-3-babel-and-a-look-into-the-future
A Beginner’s Guide to npm — the Node Package Manager
关注微信公众号,发现更多精彩内容