最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Webpack 初探(一)

    正文概述 掘金(炽翎)   2021-02-05   505

    前言

    有一段时间没有做积累和学习了,近期学习的内容会陆陆续续更新进来。

    Webpack 应该会写一个系列吧,从 初探 => 深入 => 实战

    创建 Demo(使用 lerna)

    这里使用 lerna 创建一个 Monorepo,不了解 Monorepolerna 的同学可以看一下这篇文章:大型前端项目管理 - Monorepo。

    执行以下命令:

    yarn global add lerna
    mkdir demo && cd demo
    lerna init
    

    得到一个 Monorepo 的项目,目录结构是这样的:

    .
    ├── lerna.json
    ├── package.json
    └── packages
    

    然后在 packages 目录下创建一个 basic 文件夹,意味着这是一个基础 Demo。

    packages/basic 目录下创建三个文件:index.htmlindex.jsfunc.js

    <!-- index.html -->
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>basic webpack demo</title>
      </head>
      <body>
        <div id="app"></div>
        <script src="./bundle.js"></script>
      </body>
    </html>
    
    // func.js
    function show(content) {
      document.querySelector('#app').innerHTML = `Hello, ${content}!`;
    }
    
    module.exports = show;
    
    // index.js
    const show = require('./func');
    
    show('Webpack');
    

    这个时候还没有 bundle.js 这个文件,所以这个时候网页还不能正常显示内容。

    稍后需要使用 Webpackindex.jsfunc.js 打包,生成最终需要的 bundle.js

    执行以下命令:

    cd packages/basic
    yarn init
    yarn add webpack webpack-cli --dev
    

    初始化 basic,并安装好 Webpack,接下来需要对 Webpack 进行配置并打包生成最终需要的 bundle.js

    basic 中创建 Webpack 的配置文件 webpack.config.js

    // webpack.config.js
    const path = require('path');
    
    module.exports = {
      // 开发者工具 不需要开发调试
      devtool: false,
      // 开发模式 不进行代码压缩
      mode: 'development',
      // 入口文件
      entry: './index.js',
      output: {
        // 输出文件名称
        filename: 'bundle.js',
        // 输出文件路径
        path: path.join(__dirname, './'),
      },
    };
    

    然后打开 package.json,添加一条 npm scripts

    // package.json
    {
      "name": "basic",
      "version": "1.0.0",
      "main": "index.js",
      "repository": "https://github.com/wjq990112/Learning-Webpack",
      "author": "wjq990112",
      "license": "MIT",
      "scripts": {
        "build": "webpack"
      },
      "devDependencies": {
        "webpack": "^5.19.0",
        "webpack-cli": "^4.4.0"
      }
    }
    

    执行以下命令:

    yarn build
    

    使用 Webpackindex.jsfunc.js 进行打包。

    打包完成后 basic 中就会多生成一个 bundle.js。这个时候再使用浏览器打开 index.html,这个时候网页就显示出 Hello, Webpack!

    美化 Demo(使用 loader)

    基本的 Demo 已经创建好了,接下来对这个网页做一下美化,让 Hello, Webpack! 这段文字水平居中。

    Webpack 拥有 loader 机制,可以使用 loader 将非 JavaScript 的文件转换为可以在 JavaScript 使用的代码。

    basic 创建一个样式文件 index.css

    /* index.css */
    #app {
      text-align: center;
    }
    

    index.js 中引入:

    // index.js
    require('./index.css');
    
    const show = require('./func');
    
    show('Webpack');
    

    这个时候执行 yarn build 会报错,因为 Webpack 原生不支持 CSS,需要使用对应的 loaderCSS 做转换。

    执行以下脚本:

    yarn add style-loader css-loader --dev
    

    然后修改 webpack.config.js

    // webpack.config.js
    const path = require('path');
    
    module.exports = {
      // 开发者工具 不需要开发调试
      devtool: false,
      // 开发模式 不进行代码压缩
      mode: 'development',
      // 入口文件
      entry: './index.js',
      output: {
        // 输出文件名称
        filename: 'bundle.js',
        // 输出文件路径
        path: path.join(__dirname, './'),
      },
      module: {
        rules: [
          {
            // 正则匹配后缀名为 .css 的文件
            test: /\.css$/,
            use: ['style-loader', 'css-loader'],
          },
        ],
      },
    };
    

    这里通过正则匹配了所有后缀名为 .css 的文件,将 CSS 文件交给 css-loaderstyle-loader 进行处理。

    • use 的执行顺序是从后向前执行
    • loader 支持传入参数,有两种方式:
      1. UrlSearchParams
      2. Options Object

    所以这里的应该是先将 .css 结尾的文件交由 css-loader 进行处理,再交由 style-loader 将其注入到 bundle.js 中,通过 DOM 操作在 <head></head> 标签中注入样式。

    执行以下命令:

    yarn build
    

    现在进行打包就不会报错了,打开 bundle.js 会发现其中有一段非常长的处理样式的代码,将样式代码以 <style></style> 标签的形式注入到了 <head></head> 标签中。

    回到页面,Hello, Webpack! 实现了水平居中。打开控制台,可以看到 <head></head> 标签中多了一个 <style></style> 标签,其中的内容就是 index.css 当中的内容。

    核心代码:

    function insertStyleElement(options) {
      var style = document.createElement('style');
      var attributes = options.attributes || {};
    
      if (typeof attributes.nonce === 'undefined') {
        var nonce = true ? __webpack_require__.nc : 0;
    
        if (nonce) {
          attributes.nonce = nonce;
        }
      }
    
      Object.keys(attributes).forEach(function (key) {
        style.setAttribute(key, attributes[key]);
      });
    
      if (typeof options.insert === 'function') {
        options.insert(style);
      } else {
        var target = getTarget(options.insert || 'head');
    
        if (!target) {
          throw new Error(
            "Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.",
          );
        }
    
        target.appendChild(style);
      }
    
      return style;
    }
    

    但是使用这样的方式将样式代码注入到 HTML 中有两个问题:

    1. 增加了 DOM 操作
    2. bundle.js 代码体积增大

    既然有这样的问题,能不能将 CSS 文件单独抽取出来,不将其打包至 bundle.js 中呢?

    优化 Demo(使用 plugin)

    这个时候就需要对 bundle.js 做一些优化,将 CSS 文件与 bundle.js 分离,然后可以单独引入 CSS 样式文件。

    Webpack 拥有 plugin 机制,可以使用 plugin 在打包过程中的某个阶段对代码进行处理。

    要分离样式文件,就需要使用到一个 pluginMiniCssExtractPlugin

    执行以下命令:

    yarn add mini-css-extract-plugin --dev
    

    安装 MiniCssExtractPlugin,然后再对 webpack.config.js 做一些修改:

    // webpack.config.js
    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      // 开发者工具 不需要开发调试
      devtool: false,
      // 开发模式 不进行代码压缩
      mode: 'development',
      // 入口文件
      entry: './index.js',
      output: {
        // 输出文件名称
        filename: 'bundle.js',
        // 输出文件路径
        path: path.join(__dirname, './'),
      },
      module: {
        rules: [
          {
            // 正则匹配后缀名为 .css 的文件
            test: /\.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
          },
        ],
      },
      plugins: [new MiniCssExtractPlugin()],
    };
    

    再执行 yarn build,会发现在当前目录下多了一个 main.css

    回到 index.html 中,将分离出来的 main.css 单独引入:

    <!-- index.html -->
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>basic webpack demo</title>
        <link rel="stylesheet" href="./main.css" />
      </head>
      <body>
        <div id="app"></div>
        <script src="./bundle.js"></script>
      </body>
    </html>
    

    再回到页面中,Hello, Webpack! 也实现了水平居中。打开控制台,可以看到样式 main.css 被正确引入了。


    起源地下载网 » Webpack 初探(一)

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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