Skip to content

Webpack 3.x 学习-第一天 #5

@shushu2013

Description

@shushu2013

学习资料

深入浅出 Webpack

Webpack3.X版 成神之路 全网首发 (共24集)

这个是跟着上面的资料学习 Webpack 3.X 整理记录下来的学习笔记

Webpack 学习第一步

1、初始化项目并安装 Webpack

系统要求:

    NodeJS 版本 5.0.0 以上
    npm (国内把 cnpm 也安装上)
    编辑器推荐使用 VSCode

新建一个 Web 项目,并初始化

mkdir webpack-demo
cd webpack-demo
npm init    // 会生成一个 package.json 文件,包含项目的相关信息

安装 Webpack 到本地项目(之后所有命令都是在新建的 webpack-demo 目录下进行)

cd webpack-demo

// 国内使用 cnpm 下载
cnpm install --dev-save webpack     // 命令简写:cnpm i -D webpack

// 安装指定版本
cnpm i -D webpack@<version>

// 卸载
npm uninstall -D webpack

2、运行本地安装的 Webpack

官方推荐的 Webpack 配置文件为 webpack.config.js,并且放在项目根目录下

cd webpack-demo
touch webpack.config.js // linux 命令

// windows 下有 cmd 和 powershell 终端,我的 VSCode 里用的是 powershell 终端
copy nul > test.js  // cmd 下创建 test.js 文件
del test.js         // cmd 下删除 test.js 文件

new-item test.js -type file // powershell 下创建 test.js 文件
// 简写:new-item test.js -t f 
rm test.js                  // powershell 下删除 test.js 文件
  • 在项目根目录下运行 ./node_modules/.bin/webpack -v 查看 Webpack 版本

  • npm script 里定义 Webpack 相关任务(会优先使用本项目下安装的 Webpack),定义在项目的 package.json 文件中的 scripts 项中

"scripts": {
    "start": "webpack --config webpack.config.js"
}

之后可以执行: npm run start 来运行 start 这个任务

3、初始项目结构规范

一般我们开发环境的源码放在项目根目录下的 src 目录下,经过 Webpack 构建后生成的生产环境代码放在 dist 目录下

现在,在 src 目录下创建 JS 执行入口文件 index.js,在 dist 目录下创建页面入口文件 index.html

dist 目录下的页面入口文件 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>learn webpack</title>
</head>
<body>
    <div id="app"></div>
    
    <!--导入 Webpack 输出的 JavaScript 文件-->
    <script src="./bundle.js"></script>
</body>
</html>

src 目录下的 JS 执行入口文件 index.js

function show(content) {
  window.document.getElementById('app').innerText = 'Hello,' + content;
}
show('Webpack');

webpack.config.js 基础配置

const path = require('path');

module.exports = {
    // 入口文件的配置项
    entry: {
        index: './src/index.js'
    },
    // 出口文件的配置项
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    // 模块:例如转换 es6, less, 压缩, 图片转换等...
    module: {},
    // 插件,用于生产模板和各项功能
    plugins: [],
    // 配置 webpack 开发本地服务器功能
    devServer: {}
}

此时项目目录结构如下:

|-- webpack-demo    
        |-- dist
        |     |__ index.html
        |-- node_modules
        |-- src
        |     |__ index.js
        |__ package.json
        |__ webpack.config.js

4、初次运行 Webpack 构建命令

之前已经在 package.json 文件中定义了 start 任务

"scripts": {
    "start": "webpack --config webpack.config.js"
}

此时在终端中执行 npm run start 命令来执行相应的 Webpack 构建命令,你会发现在 dist 目录下生成了 bundle.js 文件

在浏览器中打开 dist 目录中的 index.html,就会显示 Hello,Webpack

Webpack 学习第二步

1、重构项目

1.1 项目需求:
  • dist 目录下的 index.html 能根据指定的 html 模板 动态生成
  • index.html 能动态加载 Webpack 打包后生成的多个 js 文件
  • 对生成的 index.html 进行压缩(如:去除注释、空格等)
  • 如果某个文件内容改动,则 Webpack 打包后生成的文件名要不一样,防止浏览器缓存旧的文件

前三个需求可以通过使用 Webpack 插件 html-webpack-plugin 实现

1.2 参考资料:

html-webpack-plugin GitHub 地址
html-webpack-plugin 插件用法
深入浅出webpack教程系列4-插件使用之html-webpack-plugin配置(上)

html-webpack-plugin 内部集成了 html-minifier, 这个压缩选项同 html-minifier 的压缩选项相同
参考:html-minifier GitHub 地址

1.3 先重构我们的项目结构如下:
|-- webpack-demo    
        |-- node_modules
        |-- src
        |     |-- js
        |     |   |__ index.js
        |     |
        |     |__ index.html
        |__ package.json
        |__ webpack.config.js

src 目录下的 index.htmlhtml-webpack-plugin 插件要用到的模板文件,内容如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- 获取 html-webpack-plugin 插件配置项中的 title 信息 -->
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    <div id="app"></div>
</body>
</html>
1.4 安装 html-webpack-plugin 插件
cnpm i -D html-webpack-plugin
1.5 在 webpack.config.js 中引入并配置 html-webpack-plugin 插件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // 入口文件的配置项
    entry: {
        index: './src/js/index.js'
    },
    // 出口文件的配置项
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/bundle.js'
    },
    // 模块:例如转换 es6, less, 图片转换等...
    module: {},
    // 插件,用于生产模板等各项功能
    plugins: [
        new HtmlWebpackPlugin({
            title: 'learn webpack',         // 标题
            template: './src/index.html',   // html 模板
            filename: 'index.html',         // 生成的 HTML 名称
            inject: 'true',                 // 引入生成的 js 文件,false 则不引入
            minify: {
                removeComments : true,      //去掉注释
                collapseWhitespace : true   //去掉空行
            }
        })
    ],
    // 配置 webpack 开发本地服务器功能
    devServer: {}
}

执行 npm run start 后,会生成 dist 目录,内容如下:

|-- webpack-demo    
        |-- dist
              |-- js
              |   |__ bundle.js
              |
              |__ index.html
1.6 在 webpack.config.js 中配置出口文件名
// 出口文件的配置项
output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/bundle.js'
}

其中 filename 支持 4 种动态名称:id, name, hash, chunkhash

// 使用入口名字
filename: '[name].bundle.js'

// 使用内部块 id
filename: '[id].bundle.js'

// 对每次构建使用唯一的 hash 值,所有输出的文件都是用的这个 hash 值
// 只要有任何一个文件内容改变了,hash 值就会变
filename: '[name].[hash].bundle.js'

// 该 hash 值是基于文件自身的内容改变的,每个文件的 hash 值根据自己的内容变化
filename: '[name].[chunkhash].bundle.js'

参考资料:

webpack 关于 Output 的文档
Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

现在我们将 webpack.config.js 中出口文件的配置项改为

// 出口文件的配置项
output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name]-[chunkhash:8].js'
}

[chunkhash:8] 表示生成 8 位 hash 值

1.7 清理 dist 文件夹

以上需求都解决,但是当改变了 index.js 文件的内容时,生成了新的带 chunkhash 的文件,原先生成的旧文件并没有被删除,于是在打包前,需要清理掉 dist 文件夹,使用 clean-webpack-plugin 插件即可

参考资料

Webpack 官方文档
clean-webpack-plugin GitHub 地址

安装 clean-webpack-plugin 插件

cnpm i -D clean-webpack-plugin

webpack.config.js 中引入并配置 clean-webpack-plugin

const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {

    // ...省略其他配置
    
    plugins: [
        new CleanWebpackPlugin(['dist'])   //构建前,删除 dist 目录
    ]
}

clean-webpack-plugin 的一些配置选项

// 应该被清除的目录或文件
let pathsToClean = [
  'dist',         // 删除 'dist' 目录
  'build/*.*',    // 删除 'build' 目录下的所有文件
  'web/*.js'      // 删除 'web' 目录下所有的 js 文件
]

// 相关选项
let cleanOptions = {
  // 设置绝对路径,默认为项目根目录
  root: __dirname,

  // 是否在控制台显示清除信息
  verbose: true,
  
  // Use boolean "true" to test/emulate delete. (will not remove files).
  // Default: false - remove files
  dry: false,           

  // If true, remove files on recompile. 
  // Default: false
  watch: false,

  // Instead of removing whole path recursively,
  // remove all path's content with exclusion of provided immediate children.
  // Good for not removing shared files from build directories.
  exclude: [ 'files', 'to', 'ignore' ],

  // allow the plugin to clean folders outside of the webpack root.
  // Default: false - don't allow clean folder outside of the webpack root
  allowExternal: false
}

new CleanWebpackPlugin(pathsToClean, cleanOptions)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions