前面讲了启动本地服务器,但是本地服务起来之后只看到资源目录列表。

与正常的网页相差甚远。

本节讲解如何把js文件引入到html并把html文件编译出来。

1、新建index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- 模版,此处插入js脚本 -->
  <div>我是毛毛</div>
</body>
</html>

注释处计划插入编译后的js文件内容。

2、引入插件:html-webpack-plugin

webpack文件添加如下配置:


let HtmlWebpackPlugin = require("html-webpack-plugin")//html webpack 插件
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",//模版文件(源文件)地址
      filename: "index.html"//打包后文件名
    })
  ]
}

3、运行:

npm run dev

嗯,日常报错…

ERROR in   Error: The loader "/Users/maolijun298/Documents/demo/h5/mm_webpack/node_modules/html-webpack-plugin/lib/loader.js!/Users/maolijun298/Documents/demo/h5/mm_webpack/src/index.html" didn't return html.
  
  - index.js:330 HtmlWebpackPlugin.evaluateCompilationResult
    [mm_webpack]/[html-webpack-plugin]/index.js:330:24
  
  - index.js:237 
    [mm_webpack]/[html-webpack-plugin]/index.js:237:22
  
  - task_queues.js:93 processTicksAndRejections
    internal/process/task_queues.js:93:5
  
  - async Promise.all
  
  - async Promise.all
  


webpack 5.38.0 compiled with 1 error in 173 ms
ℹ 「wdm」: Failed to compile.

报错原因:webpackhtml-webpack-plugin版本不兼容。

解决办法:

  • 方法一:降级 webpack 版本,降到 v5.22.0 以下。
  • 方法二:修改本地的 html-webpack-plugin 源码,找到你本地的 xxx/node_modules/html-webpack-plugin/index.js325 行:
 // Evaluate code and cast to string
    let newSource;
    try {
      // fix issues: https://github.com/jantimon/html-webpack-plugin/issues/1603
      // newSource = vmScript.runInContext(vmContext);
      vmScript.runInContext(vmContext);
    } catch (e) {
      return Promise.reject(e);
    }
    // see issues: https://github.com/jantimon/html-webpack-plugin/issues/1603
    newSource = vmContext.HTML_WEBPACK_PLUGIN_RESULT;

特别鸣谢:vv_小虫

我采用降级版本的方案。

如果不知道具体降级到哪个版本,可以运行:

npm view webpack versions

查看所有webpack版本。

我这里是用了5.21.2版本:

npm install webpack@5.21.2 -D

重新安装完webpack,再次运行npm run dev

4、查看结果

服务器启动成功。

打包之后的index.html文件里自动引入了bundle.js文件:

<script src="bundle.js"></script></body>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <!-- 模版,此处插入js脚本 -->
  <div>我是毛毛</div>
<script src="bundle.js"></script></body>
</html>

5、对html文件压缩打包

1. 修改webpack文件,添加以下命令:

module.exports = {
  plugins: [//存放所有插件
    new HtmlWebpackPlugin({
      template: "./src/index.html",//模版文件(源文件)地址
      filename: "index.html",//打包后文件名
      minify: {
        removeAttributeQuotes: true,//删除双引号
        collapseWhitespace: true,//折叠空行(变成一行)
      },
    }),
  ]
}

主要是设置:removeAttributeQuotescollapseWhitespace

      minify: {
        removeAttributeQuotes: true,//删除双引号
        collapseWhitespace: true,//折叠空行(变成一行)
      },

2. 运行

npm run build

3.查看结果

<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Document</title></head><body><!-- 模版,此处插入js脚本 --><div>我是毛毛</div><script src=bundle.js></script></body></html>

index.html文件变成了一行去掉了引号(内容有逗号的引号被保留,因为去掉会有解析问题)

6、引入文件时加上hash戳

加上hash戳的目的是防止缓存

修改webpack配置:

      minify: {
        removeAttributeQuotes: true,//删除双引号
        collapseWhitespace: true,//折叠空行(变成一行)
      },
      hash: true,//引用时文件名加上hash戳

新增hash: true

查看结果:

<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Document</title></head><body><!-- 模版,此处插入js脚本 --><div>我是毛毛</div><script src=bundle.js?d595b17fe59e62f7e631></script></body></html>

可以看到之前引入的bundle.js文件后面加了hash戳<script src=bundle.js?d595b17fe59e62f7e631></script>

7、打包js文件加上hash戳

加上hash戳的目的是防止缓存
每次修改代码后,打包生成的都是新的js文件,不会覆盖原来的js文件。

将原来生成的bundle.js改为bundle.hash戳.js

1. 修改webpack配置:

output: {
    filename: "bundle.[hash].js",//打包后的文件名
    path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
  },

output里面的filename字段由原来的bundle.js修改为bundle.[hash].js

2. 运行:

npm run build

3. 查看结果:

<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Document</title></head><body><!-- 模版,此处插入js脚本 --><div>我是毛毛</div><script src=bundle.d595b17fe59e62f7e631.js?d595b17fe59e62f7e631></script></body></html>

可以看到之前引入的bundle.js文件名和文件名后面都加了hash戳<script src=bundle.d595b17fe59e62f7e631.js?d595b17fe59e62f7e631></script>

8. 规定hash戳长度

1. 修改webpack配置

output: {
    filename: "bundle.[hash:8].js",//打包后的文件名
    path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
  },

output里面的filename字段由原来的bundle.[hash].js修改为bundle.[hash:8].js

生成的文件就会由原来的20位hash戳,缩短成8位hash戳。

2. 查看结果:

<!DOCTYPE html><html lang=en><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Document</title></head><body><!-- 模版,此处插入js脚本 --><div>我是毛毛</div><script src=bundle.d595b17f.js?d595b17fe59e62f7e631></script></body></html>

可以看到之前引入的bundle.js文件名加了8位hash戳<script src=bundle.d595b17f.js?d595b17fe59e62f7e631></script>

完整webpack配置

//webpack 是用nodejs写的,是node语法

let path = require('path')//node提供的 相对路径 转 绝对路径 的插件
let HtmlWebpackPlugin = require("html-webpack-plugin")//html webpack 插件
module.exports = {
  devServer: {//开发服务器配置
    port: 3000,//端口号
    progress: true,//进度条
    contentBase: "./dist",//返回的资源目录
    compress: true//是否压缩
  },
  mode: "development",//模式,两种模式,产线模式"production"、开发模式"development"。产线模式会把编译文件进行压缩优化,代码变成一行。
  entry: "./src/aaa.js",//入口,相对路径
  output: {
    filename: "bundle.[hash:8].js",//打包后的文件名
    path: path.resolve(__dirname, "dist"),//打包后的路径(文件夹路径),必须是绝对路径,"__dirname"指当前路径
  },

  plugins: [//存放所有插件
    new HtmlWebpackPlugin({
      template: "./src/index.html",//模版文件(源文件)地址
      filename: "index.html",//打包后文件名
      minify: {
        removeAttributeQuotes: true,//删除双引号
        collapseWhitespace: true,//折叠空行(变成一行)
      },
      hash: true,//引用时文件名加上hash戳
    }),

  ]
}