• npm 6.14 + Babel 7 使用


    Babel官网

    Babel github :https://github.com/babel/babel/tree/master/packages

    Babel 在线转化:https://www.babeljs.cn/repl

    Babel 是干嘛的

    用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。下面列出的是 Babel 能为你做的事情:

    • 语法转换
    • 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)
    • 源码转换 (codemods)

    npx

    在Babel使用之前先介绍一下npx,因为后面用到npx,注意不是npm

    npx是啥

    npx是一种在npm中安装工具,也可以被单独的下载使用

    在npm 5.2.0 的时候发现会买一送一,自动安装了npx。

    也就是说 npm5.2之后,会自动安装

    npx是解决什么问题的

    再也不需全局安装任何工具只需要npx <commang>

    为什么使用npx

    全局安装劣势:

    • 占用本机空间

      npm会在machine上创建一个目录(mac是/usr/local/lib/node_modules)存放所有global安装的包, 其实node_module占用的空间比较大的

    • 版本问题:

      假如一个项目中的某一个dependency是全局安装的,也就意味着不同的开发人员使用的这个dependency版本完全基于本地的版本,也就会导致不同的开发人员使用不同的版本

    使用npx的优势也就凸显出来了:

    • 当在执行

      npx <command>
      

      的时候,npx会做什么事情?

      • 帮你在本地(可以是项目中的也可以是本机的)寻找这个 command
        • 找到了: 就用本地的版本
        • 没找到: 直接下载最新版本,完成命令要求
      • 使用完之后不会在你的本机或者项目留下任何东西

    因此优势总结:

    • 不会污染本机
    • 永远使用最新版本的dependency

    Babel使用

    配置Node项目环境

    执行

    npm init -y
    

    然后项目目录下就会创建一个package.json,如

    image-20201013144435261

    下载相应的包的命令

    npm install --save-dev @babel/core @babel/cli @babel/preset-env
    npm install --save @babel/polyfill
     
    或者简写:
     
    npm install -D @babel/core @babel/cli @babel/preset-env
    npm install @babel/polyfill
    

    (--save-dev(简写-D)表示该版本只适用于开发环境中,命令会自动帮你写在package.json的devDependencies中

    --save(或者不写)则表示该版本适用于生产环境中,命令会自动帮你写在package.json的dependencies中 )

    如:

    image-20201013144838047

    使用Babel前要下载的包的意义和用法

    @babel/core

    Babel 的核心功能在 @babel/core模块,如果某些代码需要调用Babel的API进行转码,则就需要此模块。

    用法如下

    var babel = require('@babel/core');
    // 字符串转码
    babel.transform('code();', options);
    // => { code, map, ast }
    
    // 文件转码(异步)
    babel.transformFile('filename.js', options, function(err, result) {
      result; // => { code, map, ast }
    });
    
    // 文件转码(同步)
    babel.transformFileSync('filename.js', options);
    // => { code, map, ast }
    
    // Babel AST转码
    babel.transformFromAst(ast, code, options);
    // => { code, map, ast }
    

    @babel/polyfill

    模块包括core-js和自定义regenerator runtime 来模拟完整的 ES2015+ 环境。

    Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。

    举例来说,ES6在Array对象上新增了Array.from方法。Babel就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片

    @babel/preset-env

    根据你需要支持的环境(配合targets中的浏览器信息)自动决定适合你的 Babel 插件

    @babel/cli

    @babel/cli是一个允许你从终端使用 babel 的工具。即用于命令行转码

    全局安装命令

    npm install -D @babel/cli -g
    

    基本用法如下。

    # 转码结果输出到标准输出(字符串形式输出)
    $ babel example.js
    
    # 转码结果写入一个文件
    # --out-file 或 -o 参数指定输出文件
    $ babel example.js --out-file compiled.js
    
    # 或者
    $ babel example.js -o compiled.js
    
    # 整个目录转码
    # --out-dir 或 -d 参数指定输出目录
    $ babel src --out-dir lib
    # 或者
    $ babel src -d lib
    
    # -s 参数生成source map文件
    $ babel src -d lib -s
    

    创建配置文件

    使用以下内容在项目的根目录中创建名为 babel.config.js 的配置文件:(配置文件很重要)

    module.exports = function(api){
        api.cache(true)
        const presets = [
            ["@babel/env", {
              targets: {
                ie:"10",
                edge: "17",
                firefox: "60",
                chrome: "67",
                safari: "11.1"
              },
              useBuiltIns: "usage"
            }]
          ];
          const plugins = [];
          return {
            presets,
            plugins
          }
    }
    
    //target表示你想要支持的浏览器的最低型号
    // useBuiltIns: "usage" ——由于polyfill包很臃肿,Babel 的此设置将检查你的所有代码,以查找目标环境中缺少的功能,并仅包含所需的 polyfill。
    

    开始使用

    创建src文件夹,再在里面创建index.js文件,并输入

    (x => x * 2)(1)
    

    在命令行中输入

    //表示src整个目录转码到dist目录下
    npx babel src -d dist
    

    结果如下

    image-20201013153430511

    可以看到已经被成功编译

    es6相关特性编译问题

    class 不支持

    上面安装了@babel/polyfill包 编译Promise等全局对对象没问题,但是你会发现class类 这个特性编译不了

    image-20201013154717181

    这是因为还缺少一个插件@babel/plugin-proposal-class-properties

    安装

    npm install @babel/plugin-proposal-class-properties -D
    

    在配置文件中加入插件配置

    const plugins = [
            '@babel/plugin-proposal-class-properties'
        ];
    

    此时的babel.config.js

    module.exports = function(api){
        api.cache(true)
        const presets = [
            ["@babel/env", {
                targets: {
                    ie:"10",
                    edge: "17",
                    firefox: "60",
                    chrome: "67",
                    safari: "11.1"
                },
                useBuiltIns: "usage"
            }]
        ];
        const plugins = [
            '@babel/plugin-proposal-class-properties'
        ];
        return {
            presets,
            plugins
        }
    }
    

    执行编译

    npx babel src -d dist
    

    编译结果

    image-20201013155825940

    class 编译之后出现 require()

    如果你的类比较复杂,如

    class A {
        constructor() {
            console.log('A构造方法');
        }
    }
    class B extends A{
        constructor() {
            super();
            console.log('B构造方法')
        }
    }
    

    你运行编译命令之后,你会发现,编译完成的文件是这样的

    npx babel src -d dist
    

    image-20201013164531970

    你会发现居然出现了require(),这不是node的吗,为什么编译之后会出现这个?并且你会发现直接注释掉也可以引入运行,如

    image-20201014165708058

    image-20201014165727184

    找不到require()里面的相关文件

    你顺着它引入的文件去模块里面去找,你会发现这些文件你都找不到,这是为什么,怎么解决?

    image-20201014114103630

    这时候你再用Babel编译一次,你会发现

    npx babel src -d dist
    

    编译有个警告

    image-20201014114233820

    大概意思就是没有指定corejs的版本,就是这个的原因

    首先安装corejs

    npm install --save core-js@3
    

    然后在配置文件babel.config.js中加入corejs : 3的设置选项

    这时候配置文件是这样的

    module.exports = function(api){
        api.cache(true)
        const presets = [
            ["@babel/env", {
                targets: {
                    ie:"10",
                    edge: "17",
                    firefox: "60",
                    chrome: "60",
                    safari: "11.1"
                },
                useBuiltIns: "usage",
                corejs : 3
            }]
        ];
        const plugins = [
            '@babel/plugin-proposal-class-properties',
        ];
        return {
            presets,
            plugins
        }
    }
    

    再次执行Babel编译命令

    npx babel src -d dist
    

    没有警告了

    image-20201014114736338

    再次打开,发现可以找到相关文件了

    image-20201014114918730

    但是require()还是有,浏览器不可能支持require()。babel 是怎么编译es6的模块的,怎么会出现require()?

    其实就一句话:

    babel 统一将 js 模块化语法转为 commonJS 风格。

    从Babel 6.0开始,不再直接提供浏览器版本,需要配合webpack等构建工具使用。如果你的项目相当简单,并不需要使用构建工具,而你又想在Web项目中使用ES6的语法,Babel+Browserify可以满足你的需求。

    安装Browserify

    官网:http://browserify.org/

    github:https://github.com/browserify/browserify

    npm install browserify -D
    

    执行Browserify编译

    npx browserify ./dist/testClass.js -o test.js
    

    结果如下image-20201014142650790

    编译是编译完了,还是有require(),但是好像自己实现了,那html页面引入怎么用呢?

    看了下生成的结构

    image-20201014181235622

    这是自调用的闭包,页面直接引入不可能可以调用的,那怎么在html直接引入调用呢?出现这种情况是为什么呢?这是因为

    默认情况下,Browserify不允许从浏览器序列化代码之外访问模块。如果要调用浏览器序列化模块中的代码,则应该将代码与模块一起浏览

    参考:https://cloud.tencent.com/developer/ask/109752

    npx browserify ./dist/testClass.js --standalone Main -o testClass.js
    

    设置导出到全局的模块

    来到我们使用Babel编译后的文件

    加入模块导出语句

    例:

    module.exports = B;
    

    image-20201016160245279

    执行编译
    其实就是将我们导出的模块挂载到window对象下,使我们页面能够直接访问

    #npx browserify [Babel编译后的文件路径] --standalone 导出的模块名 -o 导出的文件位置
    npx browserify ./dist/testClass.js --standalone B -o testClass.js
    

    页面引入执行

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--<script src="./dist/testClass.js"></script>-->
        <script src="testClass.js"></script>
    </head>
    <body>
    
    <script>
        console.log(B);
    </script>
    </body>
    </html>
    

    运行结果

    image-20201016160740224

  • 相关阅读:
    算法(Java实现)—— KMP算法
    算法(Java实现)—— 动态规划算法
    算法(Java实现)—— 分治算法
    算法(Java实现)—— 二分搜索算法
    JDBC(八)—— 数据库连接池
    JDBC(七)—— Dao层操作
    JDBC(六)—— 数据库事务
    JDBC(五)—— 批量插入数据
    JDBC(四)—— Blob类型操作
    Myeclipse10.X安装findbugs插件记录
  • 原文地址:https://www.cnblogs.com/makalochen/p/13809397.html
Copyright © 2020-2023  润新知