webpack4从零开始构建(一)

原创 Lin_Grady 教程 webpack 42阅读 6 天前 举报

前言

之前一段时间工作原因把精力都放在小程序上,趁现在有点空闲时间,刚好官方文档也补充完整了,我准备重温一下 webpack 之路了,因为官方文档已经写得非常详细,我会大量引用原文描述,主要重点放在怎么从零构建 webpack 代码上

概念

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(static module bundler)。在 webpack 处理应用程序时,它会在内部创建一个依赖图(dependency graph),用于映射到项目需要的每个模块,然后将所有这些依赖生成到一个或多个 bundle。

核心:

  • 入口(entry)
  • 输出(output)
  • 加载器(loader)
  • 插件(plugins)

安装

因为最高版本 nodejs 有点问题,所以建议用@9.0,当然用 10 也是可以的,只是每次都会警告太烦了.
安装依赖你们也可能选择其他安装方式

yarn add webpack

webpack4+版本还需要安装

yarn add webpack-cli

完成之后打开目录下的 package.json 可以看到当前依赖

准备工作

根目录新增 index.html

创建 src 目录,新增 style.scssindex.js 备用

正常打开 index.html 没毛病

起步

根目录新增 webpack.config.js 文件

index.html 的 js 引用路径替换成输出路径

执行命令

打包完成之后直接打开 index.html 看,没毛病.

npx

npx 是 npm@5.2.0+后出现的工具,总的来说用法有几个

直接执行命令

一般我们会在 package.json 配置一些命令然后执行,例如

npm run xxx

但是我们可以直接用 npx 运行

npx xxx

临时安装调用

npx create-react-app my-cool-new-app

执行这行命令 npx 会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装!帮你下载并且执行 create-react-app,完了以后还不会留下痕迹

因为我们已经安装过 webpack 了,这么长的命令还是直接在 package.json 配置调用吧

mode

刚才打包的时候如果在终端看到这段提示

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

这是因为 webpack4 增加的一个配置项设定运行环境,通过将 mode 参数设置为 development, productionnone,可以启用对应环境下 webpack 内置的优化。默认值为 production。业务代码中可以通过 process.env.NODE_ENV 获取到当前环境模式做些不同处理

直接在 webpack.config.js 加上解决警告

mode: 'development'

index.js改成

console.log(process.env.NODE_ENV);

重新打包查看效果

development 和 production 相同与区别

  • common
  • development
  • production

loader

因为 webpack 用于编译 JavaScript 模块,样式不在它的能力范围内,所以我们需要引入 loader 做处理.它支持引入任何其他类型的文件使用.

执行命令安装依赖

yarn add style-loader css-loader sass-loader node-sass

修改一下 webpack.config.js

注意一下引用顺序,处理是从右到左的,所以上面会先编译样式转成模块再注入.

index.js 引入样式

import "./style.scss";

package.json 配置执行命令

"dev": "webpack"

执行命令

npm run dev

执行完看 dist 文件夹还是只有 main.js,刷新页面看到样式已经被内嵌入页面的 head 位置了.

还有其他的一些文件如图片,字体,文档等官方文档很详细了,这里略过,直接安装依赖

yarn add file-loader csv-loader xml-loader html-loader

图片处理

当你们在 js 引入图片的时候,该图像将被处理并添加到 output 目录,并且变量将包含该图像在处理后的最终 url,例如

同样标签中的图片和样式中的图片也会分别使用 html-loader/css-loaderj 进行类似的处理

接下来修改 webpack.config.js

管理输出

上面我们已经完成了基本的 webpack 使用,接着随着项目增大我们可能会新增多个入口,切割多份代码,这时候继续写死输出资源名字就不合适了,所以我们接下来会引入动态命名.

output.filename 有一些可用的模板

模板描述
[hash:length(默认 20)]模块标识符(module identifier)的 hash
[chunkhash:length(默认 20)]]chunk 内容的 hash
[name]模块名称
[id]模块标识符(module identifier)
[query]模块的 query,例如,文件名 ? 后面的字符串

然后我们修改 webpack.config.js 输入文件名

filename: '[name].bundle.js'

到了这一步就已经能够输出文件了.但是别急,还有一个关键问题是我们怎么动态引入文件?

plugin

HtmlWebpackPlugin

HtmlWebpackPlugin 可以生成创建 html 入口文件,动态引入编译后的外部资源.
执行命令安装依赖

yarn add html-webpack-plugin

运行命令后看到 dist 文件夹多了一个 index.html,这就是我们动态创建的入口文件了,直接打开看看效果.

clean-webpack-plugin

执行命令安装依赖

yarn add clean-webpack-plugin

这个插件可以帮你每次构建之前先删除一些没用的遗留文件,推荐每次打包前先删除整个 dist 文件
接下来修改 webpack.config.js, plugin 内新增插件

webpack-dev-server

webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)
执行命令安装依赖

yarn add webpack-dev-server

然后我们修改 webpack.config.js 新增配置

在 package.json 里新配置一条命令

"start": "webpack-dev-server"

运行命令之后会自动帮你从浏览器中启动页面http://localhost:8080/,后续一直监听代码变化,改动之后会自动刷新页面看到效果.
注意的是 webpack-dev-server 输出的文件只存在于内存中,不输出真实的文件

模块热替换(Hot Module Replacement 或 HMR)

刚才的 webpack-dev-server 配置虽然方便,但是是属于整体重载,很多时候我们只是修改一些小地方的话没必要这么耗费资源
模块热替换功能会在应用程序运行过程中替换、添加或删除模块,无需重新加载整个页面。

第一步,devServer 里 hot 替换成 hotOnly 配置
第二步,引入 webpack,plugin 里加入

new webpack.HotModuleReplacementPlugin()

webpack.config.js 整体大概如此

你们可以新建一个模块例如test.js

然后 index.js 修改如下

然后分别修改 index.js 和 test.js 看看控制台更新情况,现在更新范围仅限test.js文件了

其他代码和框架

社区还有许多其他 loader 和示例,可以使 HMR 与各种框架和库(library)平滑地进行交互……

  • React Hot Loader:实时调整 react 组件。
  • Vue Loader:此 loader 支持用于 vue 组件的 HMR,提供开箱即用体验。
  • Elm Hot Loader:支持用于 Elm 程序语言的 HMR。
  • Redux HMR:无需 loader 或插件!只需对 main store 文件进行简单的修改。
  • Angular HMR:No loader necessary! A simple change to your main * NgModule file is all that's required to have full control over the HMR APIs.没有必要使用 loader!只需对主要的 NgModule 文件进行简单的修改,由 HMR API 完全控制。

tree shaking

webpack 2 正式版本内置支持 ES2015 模块(也叫做 harmony 模块)和未引用模块检测能力。新的 webpack 4 正式版本,扩展了这个检测能力,通过 package.json 的 "sideEffects" 属性作为标记,向 compiler 提供提示,表明项目中的哪些文件是 "纯净",由此可以安全地删除文件中未使用的部分。

基于 ES6 的静态引用,tree shaking 通过扫描所有 ES6 的 export,找出被 import 的内容并添加到最终代码中。 webpack 的实现是把所有 import 标记为有使用/无使用两种,在后续压缩时进行区别处理。

我们可以先看看效果,在test.js下新增方法

index.js修改如下

运行命令之后然后打开dist目录下的文件找到这段编译代码,即使index.js引用了dead方法,但是没有使用的话编译文件依然会删除

按理说应该会包含dead方法引入,但是不知道是不是webpack4优化了这些步骤免去我们手动解决的烦恼,后续再研究.

source map

应该都知道用来映射代码方便调试

devtool构建速度重新构建速度生产环境品质(quality)
(none)++++++yes打包后的代码
eval++++++no生成后的代码
cheap-eval-source-map+++no转换过的代码(仅限行)
cheap-module-eval-source-mapo++no原始源代码(仅限行)
eval-source-map--+no原始源代码
cheap-source-map+oyes转换过的代码(仅限行)
cheap-module-source-mapo-yes原始源代码(仅限行)
inline-cheap-source-map+ono转换过的代码(仅限行)
inline-cheap-module-source-mapo-no原始源代码(仅限行)
source-map----yes原始源代码
inline-source-map----no原始源代码
hidden-source-map----yes原始源代码
nosources-source-map----yes无源代码内容

+++ 非常快速, ++ 快速, + 比较快, o 中等, - 比较慢, -- 慢

配置环境

项目开发过程一般至少分开发环境和生产环境

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

执行命令安装依赖webpack-merge,这个插件可以合并配置文件输出

yarn add webpack-merge

创建公用配置文件webpack.common.js

创建生产配置文件webpack.dev.js

创建生产配置文件webpack.prod.js

创建开发环境文件webpack.server.js

最后package.json命令配置修改如下:

第一阶段构建基本完成了,然后我们可以再深度拓展一下

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复