最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 手把手带你搭建一个简单的webpack脚手架(一)

    正文概述 掘金(半斤代码)   2021-06-01   466

    注:本文webpack版本为5以上

    webpack是什么?

    简而言之,webpack是对于现代js应用程序的静态模块打包器。官网上的图片也简明的说明了相应的关系。在项目中,因为各类文件资源相互依赖(比如html引入了image、字体资源等等)。webpack可以通过分析文件之间的依赖构建的依赖图,然后递归的通过依赖图将多种资源整合构建成最后的静态资源。但具体原理并不是本文的深入点,这里大概有一个印象为主,让我们接着下一步。

    手把手带你搭建一个简单的webpack脚手架(一)

    初始化项目

    首先我们需要创建一个项目,初始化npm,并在本地安装webpack和webpack-cli。(下面是在终端执行的命令行)。

    mkdir webpack-demo
    cd webpack-demo
    npm init -y
    npm install webpack webpack-cli --save-dev
    

    现在,我们在根目录下创建以下目录文件和相应的内容。

    项目目录:

    webpack-demo
      |- package.json
    + |- index.html
    + |- /src
    +   |- index.js
    

    src/index.js

    function component() {
      const element = document.createElement('div');
    
      // Lodash, currently included via a script, is required for this line to work
      element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    
      return element;
    }
    
    document.body.appendChild(component());
    

    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Getting Started</title>
        <script src="https://unpkg.com/lodash@4.17.20"></script> 
      </head>
      <body>
        <script src="./src/index.js"></script>
      </body>
    </html>
    

    这是最原始的使用lodash库的方式,这时我们将index.html在浏览器中运行可以看到hello webpack显示在页面上,这是因为index.html通过script标签引入了lodash库。所以index.js中的_.join才能执行将['Hello', 'webpack']拼成了'Hello webpack'。但是会带来几个问题:

    1. lodash全局存在,index.js文件的执行依赖于lodash.js。
    2. 如果缺少依赖项或包含错误顺序,那么index.js甚至无法执行。
    3. lodash可能并没有使用,但是浏览器依旧会加载这个库。

    那么webpack是如何对上面几种情况进行管理的呢?

    创建捆绑包

    首先让我们先调整下项目结构。

      webpack-demo
      |- package.json
    + |- /dist
    +   |- index.html
    - |- index.html
      |- /src
        |- index.js
    

    本地安装lodash包

    首先我们需要先在项目根目录下通过npm下载相应的lodash包。

    npm install --save lodash
    

    下载后会出现node_modules文件夹。这是npm下载在本地的库保存的文件夹,打开可以看到lodash库的源码。

    然后更改下面两个文件。

    src/index.js

    +import _ from 'lodash';
    
     function component() {
       const element = document.createElement('div');
    
       element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    
       return element;
     }
    
     document.body.appendChild(component());
    

    这里的lodash是通过import进行导入的。我们再将index.html中的script标签进行更改。

    dist/index.html

     <!DOCTYPE html>
     <html>
       <head>
         <meta charset="utf-8" />
         <title>Getting Started</title>
    -    <script src="https://unpkg.com/lodash@4.17.20"></script>
       </head>
       <body>
    -    <script src="./src/index.js"></script>
    +    <script src="main.js"></script>
       </body>
     </html>
    

    然后在终端中执行npx webpack,(npx webpack 会使用webpack默认的打包配置将目前项目进行打包)就可以对项目中的文件进行打包。

    asset main.js 69.5 KiB [emitted] [minimized] (name: main) 1 related asset
    runtime modules 1010 bytes 5 modules
    cacheable modules 532 KiB
      ./src/index.js 297 bytes [built] [code generated]
      ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
    

    从上面的输出中可以看出打包了两样东西index.js和node_modules中的lodash。而这时项目文件夹会变成下面这样。

      webpack-demo
      |- package.json
    + |- package-lock.json
      |- /dist
    +   |- main.js
    +   |- main.js.LICENSE.txt
        |- index.html
      |- /src
        |- index.js
    

    mian.js就是我们打包后的产物。dist/index.html中的<script src="main.js"></script>将其导入。而src/index.js中执行了import _ from 'lodash'。所以在src/index.js中,_.join可以执行。那么如果我们没有在src/index.js中写入这句import _ from 'lodash'的话,index.js中的_.join是无法执行的。因为webpack通过对import语句的分析,可以知道当前脚本(src/index.js)是否需要引入lodash库,从而避免lodash在全局引入的污染。这也就解决了上面的那些问题。

    好的,说到这,你想必已经大致了解了webpack打包与传统script标签导入的区别。那么我们就进一步对整个工程进行配置化吧。

    创建配置文件

    webpack可以使用相应的配置文件对webpack进行配置,也可以直接命令行运行配置,这里我们使用配置文件。下面我们创建一个配置文件(webpack.config.js)。

    project

      webpack-demo
      |- package.json
      |- package-lock.json
      |- /dist
        |- main.js
        |- main.js.LICENSE.txt
        |- index.html
      |- /src
        |- index.js
    + |- webpack.config.js
    

    webpack.config.js

    const path = require('path');
    
    module.exports = {
      entry: './src/index.js', // 打包文件的入口,webpack将从这个文件开始分析整个项目的依赖结构
      output: {
        filename: 'main.js', // 输出的文件名称
        path: path.resolve(__dirname, 'dist'), // 输出的文件夹
      },
    };
    

    这里的两个字段entryoutput是表示整个webpack打包过程中的起点与终点,entry指定了打包的流程是从src/index.js开始,output则指定了输出文件的一些属性。具体可以看上面代码中的注释。

    现在我们可以运行npx webpack --config webpack.config.js来对项目进行打包。

    ..[$] <( (git)-[master]-)> npx webpack --config webpack.config.js
    asset main.js 69.5 KiB [emitted] [minimized] (name: main) 1 related asset
    runtime modules 1010 bytes 5 modules
    cacheable modules 532 KiB
      ./src/index.js 297 bytes [built] [code generated]
      ./node_modules/lodash/lodash.js 531 KiB [built] [code generated]
    

    npm scripts

    如果我们每次都要这样去输入这一大串的命令去执行的话,那么是有点费劲的,所以我们可以对package.json中的命令行进行添加。简化相关的操作。

    package.json

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

    这时,我们执行相应的npm run build,这样就可以替代npx webpack --config webpack.config.js进行webpack的打包。webpack.config.js是webpack默认的打包文件,所以npm run build后面不指定的话,也是会默认使用这个文件的。

    静态资源打包

    从前面的步骤可以看到,我们将项目下的源代码以及使用到了的js库打包起来,通过index.html引入。这样就可以搭建起来整个项目,但是webpack默认是只支持js和json文件的解析的。对于png,css这一类其他的资源是无法进行解析的。那么如果我们的项目中需要引入相应的静态资源的话,我们该怎么办呢?webpack对于这一类静态资源使用loader进行了处理。那么loader是什么?

    Loader

    Loader可以让webpack处理除了js和json的其他类型的文件。并将他们加入到webpack的资源依赖图中。那让我们来尝试为webpack增加解析less文件的功能吧。

    less文件解析

    **增加依赖,**在项目目录下中运行下面的命令。

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

    webpack.config.js

    module.exports = {
      ...
      module: {    
            rules: [
     +          {  
     +             test: /\.(css|less)$/i,
     +             use: [         
     +                   {   loader: "style-loader"   },
     +                   {   loader: "css-loader"     },
     +                  {   loader: "less-loader"  }, 
     +             ],      
     +         }, 
             ],
      },
      ...
    };
    
    • style-loader: 用来将css样式以style标签的样式注入到index.html的header中。
    • less-loader: 处理less的loader。

    project

     webpack-demo
      |- package.json
      |- package-lock.json
      |- /dist
        |- main.js
        |- main.js.LICENSE.txt
        |- index.html
      |- /src
    +   |- index.less
        |- index.js
      |- webpack.config.js
    

    src/index.less

    body {  background-color: red;}
    

    运行npm run build,可以发现打包成功。打开浏览器预览效果。

    手把手带你搭建一个简单的webpack脚手架(一)上图说明less文件被编译了。

    但是有时候我们需要处理一些css的前缀问题,用来做兼容。这时我们可以使用postcss的loader来做这件事。

    安装依赖

    npm install --save--dev autoprefixer cssnano postcss postcss-loader
    

    project

    webpack-demo
      |- package.json
      |- package-lock.json
      |- /dist
        |- main.js
        |- main.js.LICENSE.txt
        |- index.html
      |- /src
        |- index.less
        |- index.js
      |- webpack.config.js
    + |- postcss.config.js
    + |- .browserslistrc
    

    webpack.config.js

    module.exports = {
      ...
      module: {    
            rules: [
               {  
                  test: /\.(css|less)$/i,
                  use: [         
                        {   loader: "style-loader"   },
                        {   loader: "css-loader"     },
    +                   {   loader: "postcss-loader"  },
                        {   loader: "less-loader"  }, 
                  ],      
              }, 
             ],
      },
      ...
    };
    

    postcss.config.js

    module.exports = {  
            plugins: [    
                //自动添加前缀 
                require("autoprefixer"), 
    
                //优化合并css    
                require("cssnano"),
            ],
    };
    

    .browserslistrc

    > 0.25%
    last 2 versions
    

    这时我们在**src/index.less**中增加一条css样式。

    body {  
          background-color: red;
    +     transition: background-color .4s;
    }
    

    这时我们再执行npm run build打包,打开浏览器查看。

    手把手带你搭建一个简单的webpack脚手架(一)

    这表示前缀已经成功加上了。到这里less文件已经配好了。

    图片资源处理

    webpack5已经内置了对于资源模块的加载,所以与css加载的方式有一些不同。

    project

    webpack-demo
      |- package.json
      |- package-lock.json
      |- /dist
        |- main.js
        |- main.js.LICENSE.txt
        |- index.html
      |- /src
    +   |- icon.png
        |- index.less
        |- index.js
      |- webpack.config.js
    + |- postcss.config.js
    + |- .browserslistrc
    

    webpack.config.js

    const path = require("path");
    module.exports = {  
        ...
        module: {
            rules: [
                {
                    test: /\.(css|less)$/i,
                    use: [ 
                             {    loader: "style-loader",     },
                             {    loader: "css-loader",       },
                             {    loader: "postcss-loader",   },
                             {    loader: "less-loader",      },
                        ],
                },
      +         {
      +               test: /\.(png|svg|jpg|jpeg|gif)$/i, 
      +               type: "asset/resource",      
      +         },
              ],
         },
    };
    

    src/index.js

    import _ from "lodash";
    import "./index.less";
    import iconPng from "./icon.png";
    
    function component() {  
       const element = document.createElement("div");
       // Lodash, currently included via a script, is required for this line to work 
       element.innerHTML = _.join(["Hello", "webpack"], " ");  
    
       // Add the image to our existing div.  
    +  const myIcon = new Image();  
    +  myIcon.src = iconPng;  
    +  element.appendChild(myIcon);  
    
        return element;
    }
    
    document.body.appendChild(component());
    

    这时我们再执行npm run build打包,打开浏览器查看。

    手把手带你搭建一个简单的webpack脚手架(一)

    图片正常加载。

    以此类推,可以增加其他静态资源的解析。其他资源加载具体可以看官方文档。记得安装相应的loader的依赖。

    webpack.config.js

    const path = require("path");
    module.exports = {  
        ...
        module: {
            rules: [
                {
                    test: /\.(css|less)$/i,
                    use: [ 
                             {    loader: "style-loader",     },
                             {    loader: "css-loader",       },
                             {    loader: "postcss-loader",   },
                             {    loader: "less-loader",      },
                        ],
                },
                {
                     test: /\.(png|svg|jpg|jpeg|gif)$/i, 
                     type: "asset/resource",      
                },
    +           { 
    +               test: /\.(woff|woff2|eot|ttf|otf)$/i,
    +               type: "asset/resource", 
    +           },
    +           {
    +                test: /\.(csv|tsv)$/i,
    +                use: ["csv-loader"],
    +            },
    +            {
    +                 test: /\.xml$/i,
    +                 use: ["xml-loader"],
    +             },          
            ],
         },
    };
    

    下一篇


    起源地下载网 » 手把手带你搭建一个简单的webpack脚手架(一)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元