一、babel
babel是一个JS编译器,用来转换最新的JS语法,比如把ES6, ES7等语法转化成ES5语法,从而能够在大部分浏览器中运行。像箭头函数,就可以做转换。babel在执行过程中,分三步:先分析(parsing)、再转化、最后生成代码。
但babel只转换语法的话,一些最新的api是不转化的,比如Object.assign, Promise等。所以babel还提供了很多插件,也就是babel-pilofill。安装后,即可支持浏览器运行。babel-pilofill基于core-js和regenerator。但pilofill是引入全部的api支持,如果只用了部分api,可以只引入相应的模块。
babel还可以转换JSX语法,对React支持比较好
最后说明一下babel的presets,presets是指plugins的合集。另外plugins的执行过程是先出现先运行,但presents是先出现后执行。比如:
{
"plugins": [
"transform-decorators-legacy",
"transform-class-properties"
]
}
这个是先运行transform-decorators-legacy,后运行transform-class-properties,而
{
"presets": [
"es2015",
"react",
"stage-2"
]
}
是先运行stage-2,最后运行es2015。这样做是为了更好的兼容性。
二、webpack
先提一下webpack已经是第2版了,增加了很多特性。不过我们公司的项目还没来得急更新。下面介绍的也主要基于webpack 2。
简单的说webpack是一个打包工具,打包js文件,css文件,图片,html等等,它可以分析整个项目的文件结构,确认文件之间的依赖,比如一个js文件引入了另一个js文件。在这个过程中可以合成js,压缩,加入hash等,最终生成项目文件。
webpack有几个关键概念:
- Entry:入口文件, 可以是一个或多个入口文件。在多页面应用中,每个入口文件对应一个页面,比如我们经常有前台页面和后台管理页,它们分别对应两个入口;
- Output:输出文件,文件名中可以带[hash]或[chunkhash], hash是经常要用到的,当生成的文件有变化时会在文件名后跟上hash串,可以避免客户端缓存;
- Loaders:加载器,本质上是函数,接收一个资源文件返回新的文件
- Plugins:插件
- Externals:引入外部类库,使用external来排除js文件被打包入bundle
webpack把所有文件都当成模块(module),但是webpack只懂js,所以loaders起到关键作用。当然plugins也是重要功能。
webpack与babel通常是配合起来使用,一个典型的webpack配置文件如下:
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
Babel的presets、plugins和stage-x说明
presets:预设,即一组预先设定的插件,是babel插件的组合
presets与plugins同时存在的执行顺序
1. plugins运行在presets之前;
2. plugins配置项,按照声明顺序执行,从第一个到最后一个;
3. presets配置项,按照声明逆序执行,从最后一个到第一个(主要是为了确保向后兼容)
stage-x:指处于某一阶段的js语言提案
- Stage 0 - 设想(Strawman):只是一个想法,可能有 Babel插件。
- Stage 1 - 建议(Proposal):这是值得跟进的。
- Stage 2 - 草案(Draft):初始规范。
- Stage 3 - 候选(Candidate):完成规范并在浏览器上初步实现。
- Stage 4 - 完成(Finished):将添加到下一个年度版本发布中。
Webpack的loader说明
loader是一种打包的方案,webpack默认只识别js结尾的文件,当遇到其他格式的文件后,webpack并不知道如何去处理。此时,我们可以定义一种规则,告诉webpack当他遇到某种格式的文件后,去求助于相应的loader。
loader的编译顺序是从右往左依次执行的。