• webpack 和 code splitting


    Code Splitting指的是代码分割,那么什么是代码分割,webpack和code splitting又有什么样的联系呢?

    使用npm run dev:"webpack-dev-server --config ./build/webpack.dev.js。",会看不到打包生成的dist目录。

    所以我们使用一个新的,不要启用dev-server服务。使用npm run dev-build:"webpack --config ./build/webpack.dev.js"。

    这个时候我们发现,dist目录生成到了build下面。

    我们build下面放到都是webpack配置。这是因为之前webpack移动到了build目录,输出文件到地方没改。直接写dist。指的是dist目录生成在webpack同级的目录下。改成 ../dist。就可以了。

    所以webpack的配置项真的是巨多,想完全的能记住是不可能的,所以遇到打包的问题怎么办,首先是打开打包的命令行工具,然后去分析,当你打包的过程开始执行时,他一步一步具体的流程之中哪里出了问题,通过控制台,我们就可以找到这些问题,找到问题后,截取出来,然后到google或者stack overflow上去提问,搜索问题的解决方案,找到后,再去找对应文档上的配置说明,根据文档,再回头去修改我们的配置文件,改的过程中遇到新的问题,再一点一点的去解决。

    接着进入正题。Code Splitting到底是什么?代码分割到底是什么?举个例子。

    首先我们安装一个包,叫做lodash。

    npm install lodash --save

    他是一个功能集合,提供了很多工具方法,可以高性能的比如字符串拼装的一些函数。然后继续写代码

    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>html template</title>
      </head>
      <body>
        <div id='root'></div>
      </body>
    </html>
    index.js
    // 一般我们习惯用_去代替lodash。
    import _ from "lodash";
    
    console.log(_.join(['a', 'b', 'c'], '*'))

    其实他引入了一个库,在这里,使用这个库,做了一个字符串链接这样的操作。最终打印的结果应该是a*b*c这样的字符串。然后我们输入npm run dev-build打包结束后,浏览index.html。发现控制它输出了a*b*c。所以这个函数就是字符串连接的函数。

    然后我们看到lodash和我们的业务代码都被打包到一个文件中。我们到main.js有1.38M。非常大。工具库和业务逻辑统一打包到main.js里面。这种方式做打包会带来一个潜在的问题。
    第一种方式
    假设ladash有1mb,业务逻辑代码1mb。那么main.js 2mb
    打包文件会很大,加载时间会很长
    当页面业务逻辑发生变化时,又要加载2MB的内容

    那么我们需要解决这个问题,在src目录下,我再创建一个文件,叫做lodash.js。然后将lodash的引入放放到lodash.js文件里面

    lodash.js

    // 一般我们习惯用_去代替lodash。
    import _ from "lodash";
    window._ = _;
    index.js
    console.log(_.join(['a', 'b', 'c'], '*'))

    webpack.common.js

    module.exports = {
      entry: {
        lodash: './src/lodash.js',
        main: './src/index.js'
      }
    }
    再运行npm run dev-build。发现打包出来两个文件。这个时候lodash就跟index.js分开加载了。之前用户需要加载完2MB的页面才能加载页面。现在我们把main.js分成了两个文件,分别是lodash.js和index.js。这是时候我们去想,
    第二种方式
    main.js被拆成lodash.js,index.js,分别是1mb。
    当页面业务逻辑发生变化时,只要加载main.js即可。

    这种代码的拆分,就是我们代码的核心概念.CodeSplitting。没有代码拆分完全可以,但是有代码拆分会提升性能。第二种方式是我们自己做的代码分割。不够智能。在webpack里面使用一些插件,可以智能的帮我们做code split。那么我们接下来看webpack这么自动帮我们做

    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>html template</title>
      </head>
      <body>
        <div id='root'></div>
      </body>
    </html>

    index.js

    import _ from "lodash";
    console.log(_.join(['a', 'b', 'c'], '*'))

    webpack.common.js

    module.exports = {
      // 优化
      optimization: {
        // 帮我们做代码分割
        splitChunks: {
          chunks: 'all'
        }
      }
    }

    然后运行npm run dev-build。看运行结果,webpack是怎么帮我们做代码分割的。

    打包生成的文件除了main.js。还多出了一个文件,叫做vendors~main.js。我们打开main.js,发现里面有index的业务逻辑,但是并没有lodash。再打开vendors~main.js。发现他自己把lodash提取出来。我们只做了一个非常简单的配置,webpack自己就知道了当遇到这种公用的类库的时候,自动就打包生成文件。这就是我们webpack的code splitting。所以说代码分割是webpack非常有竞争力的功能

    当然,webpack里面的代码分割不仅仅可以通过这种配置完成。我们还可以通过另外一种方式进行webpack中的代码分割。之前的那种方式是,index.js的lodash和业务逻辑是同步的。webpack通过分析去做分割。那实际上。我们除了同步的去做代码分割之外,我们还可以异步的去进行加载第三方类库。

    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>html template</title>
      </head>
      <body>
        <div id='root'></div>
      </body>
    </html>

    index.js

    function getComponent() {
      // 异步调用的lodash返回回来后,会放到_这个变量里
      return import('lodash').then(( {default: _} )=>{
        var element = document.createElement('div');
        element.innerHTML = _.join(['1', ' ', '2'], '-');
        return element;
      })
    }
    
    getComponent().then(element => {
      document.body.appendChild(element);
    })

    然后npm run dev-build。发现会报错

    说不支持这种动态import的方式。这个时候我们需要一个webpack的第三方库。帮助我们去支持这种引入方式。

    npm install babel-plugin-dynamic-import-webpack --save-dev
    .babelrc
    {
      "presets": [
        ["@babel/preset-env",{
          "targets": {
            "chrome": "67",
          },
          "useBuiltIns": "usage",
          "corejs": 3
        }],
        "@babel/preset-react"
      ],
      "plugins": ["babel-plugin-dynamic-import-webpack"]
    }

    然后重新的去打包,已经没有问题了。这个时候,我们再打开dist目录。除了main.js,还有一个0.js。main.js只有业务代码。0.js里面打包了lodash。也就是说,webpack在做同步性质的打包的时候,直接上面 import _ from 'lodash'。然后他会分析代码,自动的分割出lodash。现在代码是异步加载的时候。webpack也会去做代码的分割。

    总结:

    1、代码分割跟webpack无关

    2、所以webpack分割代码有两种方式,一种是同步的方式,靠
    optimization: {
      // 帮我们做代码分割
      splitChunks: {
        chunks: 'all'
      }
    },
    这个配置。

    一种是异步的方式,无需做任何配置,会自动进行代码分割。需要额外的安装 babel-plugin-dynamic-import-webpack 支持。



  • 相关阅读:
    C# 线程安全的操作控件
    C# 使用HttpListener创建简易Web服务器
    PHP mjpeg 连续图片格式生成
    XAMPP PHP开发环境安装备忘
    dnspod CURL模拟访问
    在MAC上使用Fiddler抓包手机
    解决关于docker: Error response from daemon: endpoint with name v5 already exists in network bridge.
    【电子政务】政务服务事项相关概念知识:事项办理深度 四级标准
    转:脱机环境下window 使用pycharm 连接cx_oracle 连接数据库
    转 shell if判断写成一行 和 shell中如何注释掉一段话
  • 原文地址:https://www.cnblogs.com/wzndkj/p/10802825.html
Copyright © 2020-2023  润新知