You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// enum.js 混用了 import 和 modules.exportsimport{i18next}from'gm-i18n'letenum={
a, b
}modules.exports=enum// 引用模块import{a}from'enum'// 提示// export 'a' was not found// console 输出// enum.js:347 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
babel7主要变化
废弃 babel-preset-stage-x
babel团队认为,非标准的特性是不稳定的(通过stage来推进),按照stage来划分需要花很多精力来维护。
对应
stage < 3
的plugin
也修改了命名,从@babel/plugin-transform-*
改为@babel/plugin-proposal-*
proposal
表示这只是一个提案中的非标准特性,随时可能变化,使用前要考虑清楚。废弃 babel-preset-es20xx
使用 babel-preset-env
不需要自己决定去用哪些
preset
,而是由env
自动的根据要支持的环境启用相应的preset
使用 Scoped Packages
更加清晰,易于区分 official package 和 community package
如:
babel-core -> @babel/core
babel-preset-env -> @babel/preset-env
迁移步骤
# 会修改 babelrc 和 package.json npx babel-upgrade --write
这样就很快完成了 babel7 的升级,但是还不够。
preset-stage-0
,升级后实际上很多proposal-plugin
是没用到的(扫下每个插件的文档)babel7
的 config-file 也有一些变化,简单来说,它提供了两种配置babel.config.js
和.babelrc
。babel.config.js
作为整个项目通用的配置,可作用于node_modules
。而.babelrc
只作为所在package
的配置,不会影响到其他package
。这意味着我们项目根目录下配置的
.babelrc
对node_modules
是不起作用的,而我们很多库都依赖babel
的转译。解决:项目根目录新建个 babel.config.js ,同时删掉没用到的 proposal-plugin (package.json中也对应删除),结果如下。
babel-transform-runtime
babel 在转换语法的时候会生成一些helper(如 class 的 classCallCheck 等),@babel/plugin-transform-runtime 这个插件会将所有生成 helper 的地方,统一从
@babel/runtime
引入,减少了冗余代码。在
babel.config.js
中添加@babel/plugin-transform-runtime
,然后 install因为我们的编译包括 node_modules,要忽略
@babel/runtime
本身的处理。node_modules下的包可能使用了多种模块格式,而
babel-plugin-transform-runtime
默认是添加import
语句,在wabpack
中同一模块下,import
语句不能和module.exports
同时使用 (babel文档 webpack相关issue)(PS: 原来可以是因为 babel 默认会将所有的模块转化成 cjs ,再传给 webpack。但是这样无法做 tree-shaking,下文会提到)
所以添加配置。
polyfill
polyfill 部分变化不大,继续走 script 引入,不经过 webpack 打包。
tree-shaking
webpack
在production mode
会自动进行tree-shaking
优化,消除未使用到的模块代码,原理是通过 es6 module 的静态分析。需要配置
babel
不转换我们的module
,给 env 加个配置,让webpack
来处理模块。我们的代码中(业务代码、库)可能会混用
import
和modules.exports
,这在webapck
中是不允许的。issue如下代码会报错
解决:统一只使用es6模块。也可以配置babel把模块先转换成cjs格式,但是这样webpack就不能做tree-shaking,不推荐
一般而言,
tree-shaking
对业务代码没多大作用,主要是针对 node_modules 下的库。webpack4 新增了sideEffects
选项,进一步优化了tree-shaking
的结果。可以看下Webpack 中的 sideEffects 到底该怎么用?简单来说,如果一个模块的export没有被任何文件用到 -> 去掉这个模块代码不会产生任何影响(反例是polyfill)-> 那就可以设置 sideEffects:false
对于我们自己发布的库,统一使用 es6 module,并且在
package.json
中加上sideEffects: false
(也可以设置为具体的文件),这样跟着业务代码一起打包,就能通过tree-shaking
去除没用到的模块代码(例如我们的图标库gm-svg
,针对不同的项目去掉没用到的图标)。最终...
最后的
babel.config.js
文件内容如下package.json
新增的依赖如下The text was updated successfully, but these errors were encountered: