Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在webpack中使用babel来编译你的es6和es7 #3

Open
muwoo opened this issue Dec 29, 2017 · 0 comments
Open

在webpack中使用babel来编译你的es6和es7 #3

muwoo opened this issue Dec 29, 2017 · 0 comments

Comments

@muwoo
Copy link
Owner

muwoo commented Dec 29, 2017

你需要了解的babel

babel 是一个javaScript 编译工具,babel 已经支持最新的 javascript 版本,下面我们来介绍 babel 常用的几个工具

babel-preset-env

安装:

npm install babel-preset-env --save-dev

不需要任何配置,babel-preset-env表现的同babel-preset-latest一样(或者可以说同babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017结合到一起,表现的一致)
你也可以通过配置polyfills和transforms来支持你所需要支持的浏览器,仅配置需要支持的语法来使你的打包文件更轻量级。

{
  "presets": ["env"]
}

有了上面这些调研,我们来看一下vue-cli 脚手架里有这样一段话:

{"presets": [["env", {
      "targets": {
          "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
       }
    }]]
}

通过上面的这些研究,我们知道了:

  • ">1% " 兼容全球使用率大于1%的流览器
  • last 2 versions 兼容每个游览器的最近两个版本
  • not ie <= 8 不兼容ie8及以下

说到这里,我们开始我们第一个demo,我们来编译我们的ES6 项目:

// src/test.js
export default 'hello ES6'
//  src/index.js
import test from './test'

console.log(test)
// webpack.config.js
const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: '[name].bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
       options: {
          presets: [["env", {
            "targets": {
              "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
            }
          }]]
        }
      }
    ]
  }
}

但是随着项目的复杂度增加,我们在options里面的配置会越来越多,所以我们可以利用babel 提供的.babelrc 来提供相同的用法:

// .babelrc
 presets: [["env", {
     "targets": {
          "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
}]]

babel-polyfill

babel 本身只提供预发的转换,当我们使用一些箭头函数这样的新的语法,其实在babel看来,更像是一种语法糖。但是babel不能转义一些ES6、ES7...的新的全局属性,例如 Promise 、新的原生方法如 String.padStart (left-pad) 等。这个时候我们就需要使用babel-polyfill.

npm install --save babel-polyfill

更详细的介绍可以参考:https://babeljs.cn/docs/usage/polyfill

这里主要体积一下:
Babel 转译后的代码要实现源代码同样的功能需要借助一些帮助函数,例如,{ [name]: 'JavaScript' } 转译后的代码如下所示:

'use strict';
function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
var obj = _defineProperty({}, 'name', 'JavaScript');

类似上面的帮助函数 _defineProperty 可能会重复出现在一些模块里,导致编译后的代码体积变大。Babel 为了解决这个问题,提供了单独的包 babel-runtime 供编译模块复用工具函数。

启用插件 babel-plugin-transform-runtime 后,Babel 就会使用 babel-runtime 下的工具函数,转译代码如下:

'use strict';
// 之前的 _defineProperty 函数已经作为公共模块 `babel-runtime/helpers/defineProperty` 使用
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var obj = (0, _defineProperty3.default)({}, 'name', 'JavaScript');

只不过那些需要修改内置api才能达成的功能,譬如:扩展String.prototype,给上面增加includes方法,就属于修改内置API的范畴。这类操作就由polyfill提供,所以项目中可以视情况选择不同的类型库

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant