美文网首页
手把手搭建一个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