总结了一下近来前端学习的笔记。
本文主要介绍babel
的配置方法,以及一个webpack
工程的配置文件范例。
1. Babel
现代JavaScript
标准(名为ECMAScript
)更新飞快,但是各个浏览器厂商并没有跟上更新让自己的浏览器原生支持这些新特性。Babel
是一个JavaScript
的编译器,可以把你的所使用的代码格式转换为ES5
,并提供一些垫片(polyfill)来使得当今主流的浏览器都能第一时间支持JavaScript
的最新特性。
1.1 核心组件
用下面这个命令安装babel
核心组件。
yarn add @babel/core --dev
如果你需要在命令行里使用babel
则需要安装@babel/cli
yarn add @babel/cli --dev
Babel在默认情况下什么也不会做,你输入什么它就输出什么(const label = code => code),除非你给它加上一些插件,它才会根据插件来解析文件并进行转换处理。
1.2 配置文件
在进行插件的说明以前先来看一下babel
的配置文件。
常用的配置文件有两种,一种是 js 格式的文件————你只要在项目的根目录下建一个名为babel.config.js
就行。
比如这样:
module.exports = function (api) {
api.cache(true);
const presets = [ ... ];
const plugins = [ ... ];
return {
presets,
plugins
};
}
还有一种是一个名为.babelrc
的文件,为 JSON 格式。比如这样:
{
"presets": [...],
"plugins": [...]
}
Webpack项目里多以后者(.babel
)来配置,在这片文章里我以.babelrc
为例子进行配置。
1.3 插件
所有的插件列表可以在babel
的官方网站找到。
https://babeljs.io/docs/en/plugins
因为不同的项目里所需要的功能不一样,你可以根据项目里的需求来定制需要安装哪些插件。
例如,你的项目里需要使用箭头函数,那就可以安装@babel/plugin-transform-arrow-functions
这个插件。
然后在配置文件里告诉babel
你需要使用这个插件进行转换:
{
"plugins": ["@babel/plugin-transform-arrow-functions"]
}
如果你的代码是这样的:
var a = () => {};
它会帮你转换成ES5格式的代码:
var a = function () {};
除了单个插件,babel
还提供了一些常用插件的合集。
https://babeljs.io/docs/en/presets
最常用的是@babel/preset-env
,它包括了上面所说的箭头函数和其他一些比较常用的支持ES6
的新插件。
如果你的项目是React
,还可以使用@babel/preset-react
插件集来获得JSX
语法的转换支持。@babel/preset-env
可以使用这个命令来安装:
yarn add @babel/preset-env --dev
然后再配置文件里这样配置:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}
useBuiltIns
选项是babel 7
的新功能,这个选项告诉babel
如何配置@babel/polyfill
。
它有三个参数可以使用:
①entry: 需要在webpack
的入口文件里import "@babel/polyfill"
一次。babel
会根据你的使用情况导入垫片,没有使用的功能不会被导入相应的垫片。
②usage: 不需要import
,全自动检测,但是要安装@babel/polyfill
。(试验阶段)
③false: 如果你import "@babel/polyfill"
,它不会排除掉没有使用的垫片,程序体积会庞大。(不推荐)
另外,在目前版本(博主执笔时为 2019/4/10,babel 7.4.0)如果你指定了这个配置选项(并安装了@babel/polyfill
),会收到这样一个提示:
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 the `corejs` option.
You should also be sure that the version you pass to the `corejs` option matches
the version specified in your `package.json`'s `dependencies` section. If it doesn't,
you need to run one of the following commands:
npm install --save core-js@2 npm install --save core-js@3
yarn add core-js@2 yarn add core-js@3
它的意思是你需要指定一个core-js
的版本。@babel/polyfill
其实是一个core-js
和generation runtime
(by Facebook)的合集,再加上babel
自己的一些定制。
执笔时@babel/polyfill
依赖的是core-js@2
版本,你可以无视掉这条警告。
但是你如果同时安装了@babel/register
,它依赖的是core-js@3
,所以在你的node_modules
目录下有可能安装的是第3版,会导致编译失败。
最安全的方式是yarn
安装一个版本,然后再配置文件里明示。例如"corejs": 3
。
!!注意!!babel
的插件只会转换语法,并不会转换API
。
对于ES6的内建功能(如 Promise / Set / Map),原型链的扩展(Array / Object 等)需要用垫片库(polyfill)来支持。
1.4 垫片库(polyfill)
https://babeljs.io/docs/en/babel-polyfill
就如前面所说,@babel/polyfill
其实是一个core-js
和generation runtime
(by Facebook)的合集。
你只需要安装之后在配置文件里配合@babel/preset-env
使用即可。
yarn add @babel/polyfill
垫片库会污染全局环境,对于一个独立的应用程序来说这无所谓。但是你如果开发的是一个插件,需要使用transform-runtime
`。
1.5 Transform-runtime
https://babeljs.io/docs/en/babel-plugin-transform-runtime
和前面的@babel/polyfill
有相似的功能,区别是它使用了一些helper
函数来对局部进行扩展,不会污染全局环境。
但是相对的,它无法提供原型链扩展支持。(但是公司里的大神喜欢用transform-runtime
而不是polyfill
)
例如下面这段代码将无法工作:
"foobar".includes("foo")
下面这段代码可以进行安装:
yarn add @babel/plugin-transform-runtime --dev
yarn add @babel/runtime
配置文件:
{
"plugins": ["@babel/plugin-transform-runtime"]
}
2. Webpack
模块化打包工具。配置文件为webpack.config.js
。
但是如果你想使用ES6
来写配置文件,需要把文件名改成webpack.config.babel.js
,并安装@babel/register
。
下面是一个Vue.js
工程的配置文件范例。
import webpack from "webpack";
import path from "path";
import VueLoaderPlugin from "vue-loader/lib/plugin";
export default {
entry: "./index.js",
mode: "development",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.(scss|css)$/,
use: [
"vue-style-loader",
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new VueLoaderPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
],
resolve: {
modules: ["node_modules"],
extensions: ["*", ".js", ".vue"],
alias: {
vue: "vue/dist/vue.min.js"
}
},
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000
}
}
3. 常用命令
复制粘贴下面的命令可以快速建立一个前端环境(默认已经安装Node.js
)。
初始化项目
npm init
安装全局命令
npm install --global yarn webpack webpack-cli
为项目导入 babel 和 webpack
yarn add @babel/core @babel/cli @babel/register @babel/preset-env webpack webpack-cli webpack-dev-server --dev
如果使用垫片库
yarn add @babel/polyfill
如果使用Transform-runtime
yarn add @babel/plugin-transform-runtime --dev
yarn add @babel/runtime