美文网首页
手把手搭建一个webpack配置项目

手把手搭建一个webpack配置项目

作者: 得到世界又如何我的心中只有你 | 来源:发表于2020-08-18 11:44 被阅读0次
    配置的功能包括

    1.ES6/REACT/CSS/LESS/IMG解析
    2.文件监听和热更新
    3.HTML/CSS文件生成、代码压缩、资源清理
    4.文件指纹

    1.创建一个项目,安装webpack

    前提:node环境,创建项目test-project,初始化package.json和webpack

    desktop % mkdir test-project
    test-project % cd test-project && npm init -y
    test-project % npm i webpack webpack-cli -D
    

    安装成功后看下webpack版本,目前笔者这边是4.44.1

    test-project % ./node_modules/.bin/webpack --version
    4.44.1
    

    通过vscode打开项目,根目录下创建webpack.config.js、src/index.js、src/helloworld.js
    webpack.config.js

    "use strict";
    
    const path = require("path");
    
    module.exports = {
      // 提供打包文件的入口
      entry: "./src/index.js",
      // 提供打包输出的目录
      output: {
        path: path.join(__dirname, "dist"), // 输出文件夹
        filename: "boundle.js", // 输出文件名
      },
      // 提供打包环境:production、development、none
      mode: "production",
      // 提供loader插件用于解析JSX/ES6/CSS/LESS/IMG等(由于webpack只能识别JSON和JS文件)
      module: {
        rules: [],
      },
      // 提供一些插件配置,用于解析外的处理(打包、压缩、文件生成等)
      plugins: [],
    };
    

    index.js

    import { helloworld } from "./helloworld";
    helloworld();
    

    src/helloworld.js

    export function helloworld() {
      document.write("Hello world!");
    }
    

    配置package.js的webpack打包命令执行npm run build

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

    得到dist文件以及其内容

    image.png
    在dist创建index.html,引入打包后的js文件,浏览器打开页面上正常显示:Hello world!
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Hello World!</title>
    </head>
    <body>
        <script type="text/javascript" src="boundle.js"></script>
    </body>
    </html>
    
    2.ES6/REACT/CSS/LESS/IMG解析

    loader插件:
    ES6:babel-loader、@babel/core、@babel/preset-env
    REACT:react、react-dom、@babel/preset-react
    CSS/LESS:style-loader、css-loader、less-loader
    IMG:file-loader
    安装插件

    test-project % npm i babel-loader @babel/core @babel/preset-env react react-dom @babel/preset-react style-loader css-loader less-loader file-loader -D
    

    babel的使用需要.babelrc文件的配置

    {
        "presets": [
            "@babel/preset-env", // 支持解析ES6
            "@babel/preset-react" // 支持解析REACT
        ]
    }
    

    修改webpack.config.js文件中的loader配置,rules为一个数组,每个对象是一个loader配置,test是一个校验,匹配支持该校验的文件,use指的使用何种loader,多个时使用数组(由于webpack的解析是一个自下向上的树解析过程,所以配置多个loader时,最上解析的loader放最前面)

    module: {
      rules: [
        {
          test: /.js$/,
          use: "babel-loader",
        },
        {
          test: /.css$/,
          use: ["style-loader", "css-loader"],
        },
        {
          test: /.less$/,
          use: ["style-loader", "css-loader", "less-loader"],
        },
        {
          test: /.(png|jpg|jpeg|gif)$/,
          use: "file-loader",
        },
      ],
    },
    

    创建src/test.js、src/test.css、src/test.less文件
    test.js

    import React from "react";
    import ReactDOM from "react-dom";
    import Img from "./images/test.jpg";
    import "./test.css";
    import "./test.less";
    
    class Test extends React.Component {
      render() {
        return (
          <div className="test-box">
            <span>hello react!</span>
            <img src={Img} />
          </div>
        );
      }
    }
    
    ReactDOM.render(<Test />, document.getElementById("root"));
    

    test.css

    .test-box {
        font-size: 20px;
        color    : #00f
    }
    

    test.less

    .test-box {
        img {
            width : 300px;
            height: auto;
        }
    }
    

    由于本次查看的是test.js,我们需要重新调整webpack入口配置,entry可配置多个,使用对象包裹,output调整输出的名字,使用占位符“[name]”

    // 提供打包文件的入口
    entry: {
      index: "./src/index.js",
      test: "./src/test.js",
    },
    // 提供打包输出的目录
    output: {
      path: path.join(__dirname, "dist"), // 输出文件夹
      filename: "[name].js", // 输出文件名
    },
    

    执行打包命令npm run build,添加dist/test.html,浏览器查看正常显示样式和图片

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Hello World!</title>
    </head>
    <body>
        <!-- 添加react挂载根节点 -->
        <div id="root"></div>
        <script type="text/javascript" src="test.js"></script>
    </body>
    </html>
    
    3.文件监听和热更新

    在开发环境下,由于每次修改文件我们都需要打包查看,webpack提供了文件监听和热更新的功能
    文件监听:配置package.json命令"watch": "webpack --watch" ,使用npm run watch,这时候webpack会将我们修改的文件缓存在磁盘,当文件进行修改每隔一段时间(300ms)会进行匹配替换,此时我们仍需要刷新浏览器才可以看到最新代码
    热更新:需要添加plugins插件HMR(HotModuleReplacementPlugin),安装webpack-dev-server,配置package.json命令"dev": "webpack-dev-server --open"

    test-project % npm i  webpack-dev-server -D
    
    // 提供打包环境:production、development、none
    mode: "development",
    // 提供一些插件配置,用于解析外的处理(打包、压缩、文件生成等)
    plugins: [
      // 代码热更新插件
      new HotModuleReplacementPlugin(),
    ],
    devServer: {
      contentBase: "./dist",
      hot: true,
    },
    

    注:清除dist目录重新打包,创建index.html引用test.js,执行npm run dev,当我们修改test.js后浏览器会自动刷新更新为最新的代码
    当我们使用热更新启动时,打包后的boundle文件在浏览器中是运行在localhost:8080服务端的,会与客户端浏览器建立websocket长连接,当文件发生改动,服务端会主动推送消息给浏览器,浏览器接收到后进行一个reload


    image.png
    image.png
    4.HTML/CSS文件生成、代码压缩、资源清理

    plugins插件:
    HTML文件生成、代码压缩:html-webpack-plugin
    CSS文件生成、代码压缩:mini-css-extract-plugin、optimize-css-assets-webpack-plugin、cssnano
    资源清理:clean-webpack-plugin
    安装插件

    test-project % npm i html-webpack-plugin -D
    test-project % npm i mini-css-extract-plugin -D
    test-project % npm i optimize-css-assets-webpack-plugin cssnano -D
    test-project % npm i clean-webpack-plugin -D
    

    修改webpack配置

    plugins: [
      // 生成css文件插件
      new MinCssExtractPlugin({
        filename: "[name].css",
      }),
      // css文件代码压缩插件
      new OptimizeCssAssetsPlugin({
        assetNameRegExp: /\.css$/g,
        cssProcessor: require("cssnano"),
      }),
      // html文件生成、代码压缩插件
      new HtmlWebpackPlugin({
        template: path.join(__dirname, "src/index.html"),
        filename: "index.html",
        chunks: ["index"],
        inject: true,
        minify: {
          html5: true,
          removeComments: false,
          collapseWhitespace: true,
          preserveLineBreaks: false,
          minifyJS: true,
          minifyCSS: true,
        },
      }),
      new HtmlWebpackPlugin({
        template: path.join(__dirname, "src/test.html"),
        filename: "test.html",
        chunks: ["test"],
        inject: true,
        minify: {
          html5: true,
          removeComments: false,
          collapseWhitespace: true,
          preserveLineBreaks: false,
          minifyJS: true,
          minifyCSS: true,
        },
      }),
      // 清理打包后的目录插件
      new CleanWebpackPlugin(),
    ],
    

    由于style-loader是将生成的样式插入到页面的header中,和MinCssExtractPlugin会有冲突,所以调整rules

    rules: [
      {
        test: /.css$/,
        use: [MinCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /.less$/,
        use: [MinCssExtractPlugin.loader, "css-loader", "less-loader"],
      },
    ],
    

    创建src/index.html、src/test.html,执行npm run build查看

    image.png
    代码都进行了压缩,且生成了html和css文件,浏览器查看显示正常
    5.文件指纹

    由于浏览器对一些静态文件会做缓存,当文件发生更改我们编译后虽然内容发生了变化,但名字没变化导致浏览器没检测到,所以引入了文件指纹,给生成的文件名后添加hash值
    js:chunkhash
    css:contenthash
    img:hash
    配置webpack文件(:8表示取hash值的前8位数)

    output: {
      path: path.join(__dirname, "dist"),
      filename: "[name]_[chunkhash:8].js",
    },
    module: {
      rules: [
        {
          test: /.(png|jpg|jpeg|gif)$/,
          use: [
            {
              loader: "file-loader",
              options: {
                name: "[name]_[hash:8].[ext]",
              },
            },
          ],
        },
      ],
    },
    plugins: [
      // 生成css文件插件
      new MinCssExtractPlugin({
        filename: "[name]_[contenthash:8].css",
      }),
    ]
    

    再次执行npm run build,浏览器查看显示正常


    image.png
    尾语

    至此,支持基本开发打包的项目配置就完成啦😄😄😄

    相关文章

      网友评论

          本文标题:手把手搭建一个webpack配置项目

          本文链接:https://www.haomeiwen.com/subject/vajcjktx.html