zoukankan      html  css  js  c++  java
  • 带你了解webpack的使用

    本文是一篇webpack的入门文章,简单的介绍webpack的使用,大部分来自官网指导手册:https://www.webpackjs.com/。如果想进一步学习webpack的使用,请移步官网。

    一 webpack基本安装

    webpack is a module bundler.(模块打包工具)
    webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到javascript模块以及其它的一些浏览器不能直接运行的拓展语⾔言(scss,typescript等),并将其打包为合适的格式以供浏览器使用。

    1.1 准备工作

    在开始之前,请确保安装了 Node.js 的最新版本。使用 Node.js 最新的长期支持版本(LTS - Long Term Support),是理想的起步。使用旧版本,你可能遇到各种问题,因为它们可能缺少 webpack 功能以及/或者缺少相关 package 包。

    1.2 本地安装

    最新的webpack版本是:webpack v5.0.0。

    首先我们创建一个目录,初始化 npm:

    mkdir webpack-example
    cd webpack-example
    npm init -y

    然后在本地安装 webpack,要安装最新版本或特定版本,请运行以下命令之一:

    npm install --save-dev webpack
    npm install --save-dev webpack@<version>

    如果你使用 webpack 4+ 版本,你还需要安装 cli,webpack-cli 可以帮助我们在命令行里使用npx ,webpack等相关指令。

    npm install --save-dev webpack-cli

    当你在本地安装 webpack 后,你能够从 node_modules/.bin/webpack 访问它的 bin 版本。

    我们可以通过运行一下命令,检测webpack是否安装成功:

    webpack -v      //command not found 默认在全局环境中查找
    npx webpack -v  // npx帮助我们在项⽬目中的node_modules⾥查找webpack

    1.3  全局安装(不推荐)

    以下的 npm安装方式,将使 webpack 在全局环境下可用:

    npm install -g webpack

    不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。

    二  webpack的入口和出口

    之前我们曾经说过webpack是一个打包工具,既然是打包工具,那它就应该有一个入口,当webpack处理应用程序时,就会从入口递归的构建一个依赖图,其中包含应用程序所需的每个模块,然后将所有这些木块打包成一个或多个bundle。

    webpack支持高度可配置的,我们可以通过创建webpack.config.js文件,配置webpack的入口和出口。

    2.1 入口

    入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

    每个依赖项随即被处理,最后输出到称之为 bundle的文件中。

    可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src。

    接下来我们看一个 entry 配置的最简单例子:

    webpack.config.js

    module.exports = {
        entry: "./src/index.js",  //默认的⼊入⼝⽂件
    };

    2.2 出口

    output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

    webpack.config.js

    const path = require('path');
    
    module.exports = {
        entry: "./src/index.js", 
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        }
    };

    在上面的示例中,我们通过 output.filename 和 output.path 属性,来告诉 webpack 打包后的文件名称,以及文件生成到哪里。可能你想要了解在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。

    2.3 修改package.json

    修改package.json scripts字段:有过vue react开发经验的同学习惯使用npm run来启动,我们也可以修改下,原理就是模块局部安装会在node_modules/.bin目录下创建一个软链接。

      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build":"webpack"
      },

    我们创建src/index.js文件:

    function component(){
        let element = document.createElement('div');
    
        element.innerHTML = `<pre>这是一个webpack demo</pre>`;
    
        return element;
    }
    
    document.body.appendChild(component());

    此时在命令行运行npm run build,就相当于直接运行webpack(或者npx webpack)命令,此时就会使用webpack进行打包,会在当前项目下生成一个dist文件夹:

    由于webpack打包使用的默认配置文件名称为webpack.config.js,因此我们不用指定配置文件名称,但是我们可以通过--config指定其它的配置文件,比如:

    npm run  build --config webpackconfig.js //指定webpack使用webpackconfig.js⽂文件来作为配置文件并执行

    mode

    webpack提供mode配置选项,告知 webpack 使用相应模式的内置优化.

    module.exports = {
      mode: 'production'
    };

    或者从命令行参数中传递:

    webpack --mode=production

    mode支持以下字符串值:

    • development:会将 process.env.NODE_ENV的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
    • production:会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.

    如果没有设置,webpack会将mode的默认值设置为production。开发阶段的开启会有利于热更新的处理,识别哪个模块变化。生产阶段的开启会有帮助模块压缩,处理副作用等一些功能。

    四 loader

    loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。

    本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

    在更高层面,在 webpack 的配置中 loader 有两个目标:

    • test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
    • use 属性,表示进行转换时,应该使用哪个 loader。

    4.1 简单示例

    例如,你可以使用 loader 告诉 webpack 加载 CSS 文件,或者将 TypeScript 转为 JavaScript。为此,首先安装相对应的 loader:

    npm install --save-dev css-loader
    npm install --save-dev ts-loader

    然后指示 webpack 对每个 .css 使用 css-loader,以及对所有 .ts 文件使用 ts-loader:

    webpack.config.js

    const path = require('path');
    
    module.exports = {
        entry: "./src/index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        },
        mode: 'production',
        module: {
            rules: [
                { test: /.css$/, use: 'css-loader' },
                { test: /.ts$/, use: 'ts-loader' }
            ]
        }
    };

    4.2 常见的loader

    style-loader
    css-loader
    less-loader
    sass-loader
    ts-loader //将Ts转换成js
    babel-loader//转换ES6、7等js新特性语法
    file-loader//处理图片子图
    eslint-loader
    ...

    4.3 file-loader示例

    我们具体介绍以下file-loader的使用,file-loader主要用于处理静态资源模块。

    原理是把打包入口中识别出的资源模块,移动到输出目录,并且返回一个地址名称。

    所以我们什么时候⽤用file-loader呢?
    场景:就是当我们需要模块,仅仅是从源代码挪移到打包目录,就可以使用file-loader来处理,txt,svg,csv,excel,图片资源啦等等

    npm install --save-dev file-loader

    案例webpack.config.js:

    const path = require('path');
    
    module.exports = {
        entry: "./src/index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        },
        mode: 'production',
        module: {
            rules: [
                { test: /.css$/, use: 'css-loader' },
                { test: /.ts$/, use: 'ts-loader' },
                {
                    test: /.(png|jpe?g|gif)$/,
                    //use使⽤用⼀一个loader可以⽤用对象,字符串串,两个loader需要⽤用数组
                    use: {
                        loader: "file-loader",
                        // options额外的配置,⽐如资源名称
                        options: {
                            //生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名
                            name: "[hash].[ext]",
                            //打包后的存放位置
                            outputPath: "images/",
                        }
                    }
                }
            ]
        }
    };

    修改src/index.js文件:

    import image from './image.jpg';
    
    function component(){
        let element = document.createElement('img');
    
        element.src = image;
    
        return element;
    }
    
    document.body.appendChild(component());

    运行npm run build重新打包:

    4.4 样式处理

    css-loader 分析css模块之间的关系,并合成一个css。
    style-loader将css插入到页面的style标签中。

    npm install style-loader css-loader --save-dev

    less-load 把less语法转换成css。

    npm install less less-loader --save-dev

    更多样式相关的配置可以参考https://www.cnblogs.com/zyly/p/12631745.html#_label4

    4.5 自己实现一个loader

    如果向自己定义一个loader,可以参考https://www.webpackjs.com/contribute/writing-a-loader/

    五 模块

    5.1 什么是webpack模块

    在webpack里一切皆模块,一个模块对应着一个文件。对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:

    • ES2015 import 语句
    • CommonJS require() 语句
    • AMD define 和 require 语句
    • css/sass/less 文件中的 @import 语句
    • 样式(url(...))或 HTML 文件(<img src=...>)中的图片链接(image url)

    webpack会从配置的entry开始递归找出所有依赖的模块。

    module:{
        rules:[
        {
            test:/.xxx$/,//指定匹配规则
            use:{
                loader: 'xxx-load'//指定使⽤用的loader
            }
        }
        ]
    }

    当webpack处理到不认识的模块时,需要在webpack中的module选项进行配置,当检测到是什么格式的模块,使用什么loader来处理。

    5.2 模块方法

    5.3  模块变量

    webpack中的模块变量主要有:

    module.hot

    module.exports

    module.process

     六 插件

    loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

    6.1 HtmlWebpackPlugin

    htmlwebpackplugin会在打包结束后,自动生成一个html文件,并把打包生成的js模块引入到该html中。

    npm install --save-dev html-webpack-plugin

    配置:

    • title: 用来生成页面的title元素
    • filename: 输出的 HTML文件名,默认是 index.html, 也可以直接配置带有子目录
    • template: 模板文件路径,支持加载器,比如 src/index.html
    • inject: true | 'head' | 'body' | false ,注入所有的资源到特定的template或者 templateContent 中,如果设置为 true 或者body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中
    • favicon: 添加特定的 favicon 路径到输出的 HTML 文件中
    • minify: {} | false , 传递 html-minifier 选项给 minify 输出
    • hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译
    • hash 到所有包含的脚本和 CSS文件,对于解除 cache 很有用。
    • cache: true | false,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。
    • showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML页面中
    • chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
    • chunksSortMode: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
    • excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块)

    webpack.config.js

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
    const webpack = require('webpack'); // 用于访问内置插件
    
    module.exports = {
        entry: "./src/index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        },
        mode: 'production',
        plugins: [
            new HtmlWebpackPlugin({template: './src/index.html'})
        ],
        module: {
            rules: [
                { test: /.css$/, use: 'css-loader' },
                { test: /.ts$/, use: 'ts-loader' },
                {
                    test: /.(png|jpe?g|gif)$/,
                    //use使⽤用⼀一个loader可以⽤用对象,字符串串,两个loader需要⽤用数组
                    use: {
                        loader: "file-loader",
                        // options额外的配置,⽐如资源名称
                        options: {
                            //生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名
                            name: "[hash].[ext]",
                            //打包后的存放位置
                            outputPath: "images/",
                        }
                    }
                }
            ]
        }
    };

    src/index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width,
    initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
    <div id="root"></div>
    </body>
    </html>

    测试在命令行运行npm run build,会在dist下生成index.html文件,并把打包生成的js模块引入到该html中。

    右键dist/index.html文件,run 'index/html':

    6.2 CleanWebpackPlugin 

    由于我们每次重新打包时都会在dist下生成文件,而dist目录并不会在打包前自动清理,这回导致我们不知道哪些文件时本次打包生成的。因此,在每次构建前清理 /dist 文件夹,是比较推荐的做法。

    clean-webpack-plugin 是一个比较普及的管理插件,让我们安装和配置下。

    npm install clean-webpack-plugin --save-dev

    webpack.config.js

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
    const {CleanWebpackPlugin} = require('clean-webpack-plugin');
    const webpack = require('webpack'); // 用于访问内置插件
    
    module.exports = {
        entry: "./src/index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        },
        mode: 'production',
        devServer: {
            contentBase: "./dist",
            open:true,
            port:8081
        },
        plugins: [
            new HtmlWebpackPlugin({template: './src/index.html'}),
            new CleanWebpackPlugin(),
        ],
        module: {
            rules: [
                { test: /.css$/, use: 'css-loader' },
                { test: /.ts$/, use: 'ts-loader' },
                {
                    test: /.(png|jpe?g|gif)$/,
                    //use使⽤用⼀一个loader可以⽤用对象,字符串串,两个loader需要⽤用数组
                    use: {
                        loader: "file-loader",
                        // options额外的配置,⽐如资源名称
                        options: {
                            //生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名
                            name: "[hash].[ext]",
                            //打包后的存放位置
                            outputPath: "images/",
                        }
                    }
                }
            ]
        }
    };

    webpack 提供许多开箱可用的插件!查阅我们的插件列表获取更多信息。

    在 webpack 配置中使用插件是简单直接的,然而也有很多值得我们进一步探讨的用例。

    6.3 自己定义一个插件

    如果想自己定义一个插件,可以参考博客https://www.webpackjs.com/contribute/writing-a-plugin/

    七 开发

    7.1 source map

    当 webpack 打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,如果将三个源文件(a.jsb.js 和 c.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js。这并通常没有太多帮助,因为你可能需要准确地知道错误来自于哪个源文件。

    为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。如果一个错误来自于 b.js,source map 就会明确的告诉你。

    source map 有很多不同的选项可用,请务必仔细阅读它们,以便可以根据需要进行配置。

    在这里,我们使用 inline-source-map 选项,这有助于解释说明我们的目的(仅解释说明,不要用于生产环境):

    webpack.config.js推荐配置:

    devtool:"cheap-module-eval-source-map",// 开发环境配置
    devtool:"cheap-module-source-map", // 线上⽣生成配置

    devtool,选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。

    7.2 WebpackDevServer

    每次改完代码都需要重新打包⼀次,打开浏览器器,刷新⼀次,很麻烦。我们可以安装使⽤WebpackDevServer来改善这块的体验。

    启动服务后,会发现dist目录没有了,这是因为devServer把打包后的模块不会放在dist目录下,而是放到内存中,从而提升速度。

     npm install webpack-dev-server --save-dev

    在webpack.config.js配置

        devServer: {
            contentBase: "./dist",
            open:true,
            port:8081
        },

    由于我安装的最新的webpack v5.0.0,webpack-cli v4.0.0,和webpack-dev-server不兼容,所以我卸载了webpack、webpack-cli和webpack-dev-server:

    npm uninstall webpack webpack-cli webpack-dev-server

    然后安装指定版本:

    npm install webpack-dev-server@3.10.3 webpack@4.42.0 webpack-cli@3.1.2 --save-dev

    修改下package.json,添加start脚本:

    {
      "name": "webpack-example",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build": "webpack",
        "start": "webpack-dev-server"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "file-loader": "^6.1.1",
        "html-webpack-plugin": "^4.5.0",
        "webpack": "^4.42.0",
        "webpack-cli": "^3.1.2",
        "webpack-dev-server": "^3.10.3"
      }
    }

    运行npm run start,打开页面:

    如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。webpack-dev-server 带有许多可配置的选项。转到相关文档以了解更多。

    7.3 WebpackDevMiddleware

    webpack-dev-middleware 是一个容器(wrapper),它可以把 webpack 处理后的文件传递给一个服务器(server)。 webpack-dev-server 在内部使用了它,同时,它也可以作为一个单独的包来使用,以便进行更多自定义设置来实现更多的需求。具体使用可以移步官网,官网例子展示了如何使用webpack-dev-middleware启动一个应用程序。

    八 模块热加载

    模块热替换(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。

    这么说你可能还是不太理解,那我举个例子,比如有一个录入用户信息的模块,需要输入用户名,性别,年龄信息,假设现在你已经把所有信息录入完成了,此时你突然发现还需要新增兴趣爱好信息的录入,然后你更改了代码,然后你需要手动去刷新浏览器,这样会导致所有输入的内容都丢失了,你还得重新录入一次。

    为了解决网页整体刷新导致页面数据丢失的问题,我们就可以使用模块热替换来实现。具体案例可以参考webpack的模块热替换

    注意:HMR 不适用于生产环境,这意味着它应当只在开发环境使用。

    8.1 启用HMR

    启用此功能实际上相当简单。而我们要做的,就是更新 webpack-dev-server 的配置,和使用 webpack 内置的 HMR 插件。

    修改webpack.config.js开启模块热替换:

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
    const {CleanWebpackPlugin} = require('clean-webpack-plugin');
    const webpack = require('webpack'); // 用于访问内置插件
    
    module.exports = {
        entry: "./src/index.js",
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        },
        mode: 'production',
        devtool:"cheap-module-eval-source-map",// 开发环境配置
        devServer: {
            contentBase: "./dist",
            open:true,
            port:8081,
            hot: true,               // 开启模块热替换
            hotOnly: true,           // 如果模块热替换功能不生效,则不刷新网页
        },
        plugins: [
            new HtmlWebpackPlugin({template: './src/index.html'}),
            new CleanWebpackPlugin(),
            new webpack.HotModuleReplacementPlugin()    // 使用webpack内置的模块热替换插件
        ],
        performance: {
            hints: "warning", // 枚举
            maxAssetSize: 30000000, // 整数类型(以字节为单位)
            maxEntrypointSize: 50000000, // 整数类型(以字节为单位)
            assetFilter: function(assetFilename) {
                // 提供资源文件名的断言函数
                return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
    
            }
        },
        module: {
            rules: [
                { test: /.css$/, use: 'css-loader' },
                { test: /.ts$/, use: 'ts-loader' },
                {
                    test: /.(png|jpe?g|gif)$/,
                    //use使⽤用⼀一个loader可以⽤用对象,字符串串,两个loader需要⽤用数组
                    use: {
                        loader: "file-loader",
                        // options额外的配置,⽐如资源名称
                        options: {
                            //生成的文件的文件名就是文件内容的 MD5 哈希值并会保留所引用资源的原始扩展名
                            name: "[hash].[ext]",
                            //打包后的存放位置
                            outputPath: "images/",
                            limit:2048
                        }
                    }
                }
            ]
        }
    };

    如果你发现修改了js代码,页面不会热更新,并且报如下错误:

    Ignored an update to unaccepted module,The following modules couldn’t be hot updated: (They would need a full reload!)

    在src/index.html入口文件中加入:

    if(module.hot){
        // accept itself
        module.hot.accept()
    }

    如果已经通过 HotModuleReplacementPlugin 启用了模块热替换(Hot Module Replacement),则它的接口将被暴露在 module.hot 属性下面。
    module.hot表示模块热替换(Hot Module Replacement) 是否启用。
    module.hot.accept()接受自身更新,在此模块或依赖模块更新时,在不通知父母的情况下,可以对此模块处理和重新取值。

    8.2 通过Node.js API

    当使用 webpack dev server 和 Node.js API 时,不要将 devServer 选项放在 webpack.config.js中。而是,在创建选项时,将其作为第二个参数传递。例如:

    new WebpackDevServer(compiler, options)

    想要启用 HMR,还需要修改 webpack 配置对象,使其包含 HMR 入口起点。webpack-dev-server package 中具有一个叫做 addDevServerEntrypoints 的方法,你可以通过使用这个方法来实现。这是关于如何使用的一个小例子:

    server.js

    const webpackDevServer = require('webpack-dev-server');
    const webpack = require('webpack');
    
    const config = require('./webpack.config.js');
    const options = {
        contentBase: "./dist",
        open:true,
        hot: true,               // 开启模块热替换
        hotOnly: true,           // 如果模块热替换功能不生效,则不刷新网页
    };
    
    webpackDevServer.addDevServerEntrypoints(config, options);
    const compiler = webpack(config);    //webpack 打包
    const server = new webpackDevServer(compiler, options);  //dev server
    
    //服务器开始监听
    server.listen(8081, 'localhost', () => {
        console.log('dev server listening on port 8081');
    });

    然后修改package.json脚本:

     "server": "node server.js"

    现在,在你的终端执行 npm run server将会启动应用:

    九 babel-loader

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

    • 语法转换
    • 通过 Polyfill 方式在目标环境中添加缺失的特性 (通过 @babel/polyfill 模块)
    • 源码转换 (codemods)
    • 更多! (查看这些 视频 获得启发)

    比如我们的箭头函数:

    () => console.log('hello babel')

    经过babel编译之后:

    (function(){
        return console.log('hello babel');
    });

    会编译成浏览器可识别的ES5语法。

    9.1 babel-loader使用

    babel-loader是webpack与babel的通信桥梁。babel-loader的安装:

    npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env --save-dev

    在 webpack 配置对象中,需要添加 babel-loader 到 module 的 loaders 列表中,像下面这样:

    module: {
      rules: [
        {
          test: /.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          }
        }
      ]

    遇到js文件就先用babel-loader处理,exclude表示排除 node_modules 文件夹中的文件。loader的配置就OK了,可是这样还不能发挥Babel的作用。在项目根目录下创建一个 .babelrc文件,添加代码:

    {
      "presets": [
        "@babel/preset-env"
      ]
    }

    @babel/preset-env里包含了es6转es5的转换规则.

    我们还希望能够在项目对一些组件进行懒加载,所以还需要一个babel插件:

    npm install babel-plugin-syntax-dynamic-import --save-dev

    在 .babelrc 文件中加入plugins配置:

    {
      "presets": [
        "@babel/preset-env"
      ],
      "plugins": [
        "syntax-dynamic-import"
      ]
    }

    由于babel 只转换语法(如箭头函数), 你可以使用 @babel/polyfill 支持新的全局变量,例如 Promise 、新的原生方法如 String.padStart (left-pad) 等。

    npm install --save @babel/polyfill

    在入口文件src/index.js引入就可以了:

    import "@babel/polyfill";

    当我们开发的是组件库,工具库这些场景的时候,polyfill就不适合了,因为polyfill是注入到全局变量window下的,会污染全局环境,所以推荐闭包方式:@babel/plugin-transform-runtime

    npm install --save-dev @babel/plugin-transform-runtime
    npm install --save @babel/runtime

    修改.babelrc文件:

    {
      "presets": [
        "@babel/preset-env"
      ],
      "plugins": [
        "syntax-dynamic-import",
        [
          "@babel/plugin-transform-runtime",
          {
            "absoluteRuntime": false,
            "corejs": false,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
          }
        ]
      ]
    }

    十 配置React打包环境

    1 安装@babel/preset-react

    @babel/preset-react用于react语法转译,babel-loader会编译jsx为React.createElement(...) 。

    使用通过以下命令安装:

    npm install react react-dom @babel/preset-react --save-dev

    并将 @babel/preset-react 添加到你的 babel 配置文件中:

    {
      "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
      ],
      "plugins": [
        "syntax-dynamic-import",
        [
          "@babel/plugin-transform-runtime",
          {
            "absoluteRuntime": false,
            "corejs": false,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
          }
        ]
      ]
    }

    修改src/index.js代码:

    import React, { Component } from "react";
    import ReactDom from "react-dom";
    class App extends Component {
        render() {
            return <div>hello world</div>;
        }
    }
    ReactDom.render(<App />, document.getElementById("root"));

    运行npm run start,输出如下:

    参考文章:

    [1]Babel基础知识整理

  • 相关阅读:
    explain详解与索引最佳实践
    MySQL的配置文件
    MySQL索引数据结构红黑树,Hash,B+树详解
    elasticsearch 进阶
    淘宝服务端高并发分布式架构演进之路
    http请求的header的一个小细节
    一次解决idea maven settings.xml文件不生效
    SpringBoot dev-tools vjtools dozer热启动类加载器不相同问题
    spring boot eclipse 远程调试
    vscode 同步配置
  • 原文地址:https://www.cnblogs.com/zyly/p/13809087.html
Copyright © 2011-2022 走看看