write once,run everywhere--Babel 7.x

我这一辈子都在等待着,只是不知道到底在等谁  --- 幸福终点站javascript

做为程序猿,对象历来都是 new 啊! 😂😂😂css

const GF = new Object();
GF.happy(console.log("see a film with you On this Chinese Valentine's Day"));
复制代码

前言

曾几什么时候,compile once,run everywhere 的 java 魅力无穷,吸引着不少的有志之士投入到其麾下。那时,javascript 还在为规范到底遵循谁打的热火朝天,ie 浏览器从引领 javascript 发展,到后来被嫌弃的不要不要的,写个代码还要考虑是否须要考虑兼容 ie (固然不止 ie ,这里只是为了嫌弃 ie)确实会让人奔溃。随着 Neo (Node) 的出现,自此 javascript 的发展迅速,竟有与 java 一争世界最好语言之实力。许多有志之士夜以继日苦思冥想 write once,run everywhere,终得解决之法---Babel。前端工程师喜大普奔,奔走相告,愈来愈多的前端工程师与产品经理握手言和。自此 javascript 一扫当初疲态,在高级语言的争霸中显露峥嵘,竟有称王之势。html

随意杜撰的,😉😉😉,想一想三个月以前下定决心全栈,一路走来,已被 javascript 的魅力所折服,竟有想放弃 java 的念头(俺只是担忧之后光头啊,只有光(熬)头(夜)才能变强)前端

package.json

第一次接触 javascript 的时候,内心是很抵触的,一想我心爱的 java 有 maven 做为依赖管理,我还在 html 中引入 javascript 文件,引入以前还要去依赖库下载对应版本的类库,嫌弃之情溢于言表。后来了解到了 package.json,Neo(Node) 救世主之名绝非浪得虚名啊。java

{
   "name": "fly-babel",
   "version": "1.0.0",
   "main": "index.js",
   "license": "MIT",
   "private": true,
   "scripts": {
       "babel": "./node_modules/.bin/babel src --out-dir lib"
   },
   "dependencies": {
       "@babel/runtime": "^7.5.5",
       "core-js": "3"
   },
   "devDependencies": {
       "@babel/cli": "^7.5.5",
       "@babel/core": "^7.5.5",
       "@babel/plugin-transform-runtime": "^7.5.5",
       "@babel/preset-env": "^7.5.5"
   }
}
复制代码

运行 yarn babel 将 src 下面的代码编译输出到 libnode

scripts 主要是用于运行脚本的。好比 yarn babel 或 yarn run babel 或 npm run babelreact

dependencies 主要是写的代码所需依赖库,好比你引用的工具类库 lodash ,项目打包的时候,这些依赖会打包进项目中android

devDependencies 是开发环境依赖,最终打包不会打到项目中webpack

yarn

yarn 中文文档ios

一款比 Npm 更智能强大的依赖包管理器,用的人都说好,谁用谁知道

yarn 初始化项目

yarn init
复制代码

全局安装 yarn

# Mac 真是开发利器啊
brew install yarn
 # 使用 npm 安装
npm install -g yarn
复制代码

验证 yarn 是否安装成功

yarn --version
复制代码

配置淘宝镜像

yarn config set registry http://registry.npm.taobao.org/
复制代码

安装项目依赖

yarn install
复制代码

添加项目依赖

# 添加最新版本 lodash 到生产依赖
yarn add [package]
# 添加指定版本
yarn add [package]@[version]
yarn add lodash
复制代码

添加开发环境依赖

yarn add --dev [package]
# 添加 lodash 到开发依赖
yarn add --dev lodash
复制代码

升级项目依赖

# 图形化界面
yarn upgrade-interactive --latest

yarn upgrade [package]
 # 升级到指定版本
yarn upgrade [package]@[version]
复制代码

移除依赖

yarn remove [package]
 # 移除 lodash
yarn remove lodash
复制代码

运行 package.json 中的自定义命令

yarn run 
yarn run babel
yarn babel
复制代码

Babel

记得使用是 Babel 7.x

Bablel 中文官方网站

Babel 在线转换

答应我,官方网站资料必定要看哦,毕竟是一手资料。能够先在在线转换上体验下,class 到底编译成了什么,推荐看下 Babel 7使用总结,官方文档加这篇资料差很少就明白了 Babel 了。

安装依赖

# 安装开发依赖
yarn add --dev @babel/core @babel/cli @babel/preset-env @babel/runtime @babel/plugin-transform-runtime
 # 安装项目依赖
yarn add core-js @babel/runtime
复制代码

配置文件选择---babel.config.js

js 文件可使用 javascript ,可扩展性较高,可使用 node 的 api。

.babelrc 是 json 格式,连注释都加不了,难搞哦。不过项目中的子项目仍是能够用.babelrc,babel.config.js 做为整个项目全局配置。

// babel.config.js 配置文件
/** * @author: 张攀钦 * @description: babel 全局配置 * 一、plugins优先于presets进行编译; * 二、plugins按照数组的index增序(从数组第一个到最后一个)进行编译; * 三、presets按照数组的index倒序(从数组最后一个到第一个)进行编译, */
module.exports = function (api) {
    api.cache(true);
    const babelrcRoots = [
        // Keep the root as a root
        ".",

        // Also consider monorepo packages "root" and load their .babelrc files.
        "./packages/*"
    ]
    const presets = [
        [
            "@babel/preset-env",
            {
                // 配置须要兼容的环境
                // chrome, edge, firefox, safari, ie, ios, node,android
                targets: {
                    ie: "8",
                    chrome: "67",
                    "browsers": ["> 1%", "last 2 versions", " ie>8", "android >= 4.0", "ios >= 7"]
                },
                // 是否输出启用的plugins列表
                debug: true,
                loose: true,
                // 模块使用 es modules ,配置为 "auto" 使用 commonJS 规范,
                modules: false,
                // 垫片使用 core.js
                corejs: 3,
                // 按需加载运用 polyfill
                useBuiltIns: "usage",
            },
        ],
    ];
    const plugins = [["@babel/plugin-transform-runtime", {
        corejs: 3,
        absoluteRuntime: false,
        helpers: true,
        regenerator: true,
        // 使用 es modules helpers
        useESModules: true
    }]];
    // 测试取 Node 相关变量
    if (process.env.NODE_ENV === "development") {
        console.log('开发环境', process.env);
    }
    return {
        presets,
        plugins, babelrcRoots
    };
}
复制代码

这是我目前使用的配置,之后添加新的东东了,再来补充

presets 引入一些经常使用插件集合,@babel/preset-env 这个包含 es 中经常使用的语法转换(@babel/preset-env则默认状况下将转换全部ECMAScript 2015+代码。),而不用一个个添加到 plugins

plugins 引入特殊的插件进行垫片

小试牛刀

  • 源码文件
[1, 2, 3].map((n) => n + 1);
class FlyYou {
    fly () {
        console.log('m fly you');
    }

    static sleep () {
        console.log('m sleep');
    }
}
console.log(Object.assign({}, { age: 1 }));
const arr = [1, 2, 3];
console.log('arr 是否包含 1:', arr.includes(1));
Promise.resolve('demo-1.js-Promise.resolve').then(data => console.log(data));
复制代码
  • Babel 转义以后的代码
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.promise";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";

var _context;

_mapInstanceProperty(_context = [1, 2, 3]).call(_context, function (n) {
  return n + 1;
});

var FlyYou =
/*#__PURE__*/
function () {
  function FlyYou() {}

  var _proto = FlyYou.prototype;

  _proto.fly = function fly() {
    console.log('m fly you');
  };

  FlyYou.sleep = function sleep() {
    console.log('m sleep');
  };

  return FlyYou;
}();

console.log(_Object$assign({}, {
  age: 1
}));
var arr = [1, 2, 3];
console.log('arr 是否包含 1:', _includesInstanceProperty(arr).call(arr, 1));

_Promise.resolve('demo-1.js-Promise.resolve').then(function (data) {
  return console.log(data);
});
复制代码
  • 转义分析
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
_Promise.resolve('demo-1.js-Promise.resolve').then(function (data) {
  return console.log(data);
});
复制代码

这个代码是没有办法单独在浏览器运行的,须要结合 webpack 将依赖打包运行。咱们能够看到 Promise 被 _Promise 替换,这个就是垫片(polyfill),意思就是引入新的依赖,来检查运行环境是否有 Promise 实现,有的话用原生的 Promise ,没有的话用依赖库(@babel/runtime-corejs3/core-js-stable/promise)实现的 Promise 。

@babel/polyfill 与 @babel/runtime 区别

两者都会提供垫片,可是 @babel/polyfill 会检查运行环境是否实现了 api,没有的话会直接修改原型或添加对象到 window。@babel/runtime 不会污染全局变量,Babel 7.X 两者选其一便可。推荐用 @babel/runtime。

举个例子,好比 ie 没有实现 Promise,你使用 @babel/polyfill编译以后的代码,是能够直接在浏览器控制台访问 Promise ,而 @babel/runtime 不会污染全局变量,控制台访问不到 Promise。

相关文章
相关标签/搜索