静态模块打包工具-webpack


Webpack

开始

npm  init –y //初始化npm
npm install –-save-dev webpack webpack-cli //安装webpack,webpack-cli是命令行运行//webpack
npm install –-save-dev lodash

Webpack打包资源的管理:

(1):打包入口,对不同资源的打包

(2):打包输出,bundle、chunk的概念

(3):开发

(3.1):使用服务器

(3.2):模块热替换

(3.3):构建不同的环境

(3.4):tree shaking

(3.5):代码分离

(3.6):懒加载

(3.7):缓存

四个核心概念:

入口(entry):

指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的

Entry接受三种形式的值:字符串、数组和对象

对象entry:

img

对象中的每一对属性,都代表一个入口文件。

Key可以是字符串,对应output.filename配置中的[name],也可以是路径字符串,webpack会自动生成路径目录,并将路径的最后一个作为[name]。

value如果是字符串,而且必须是合理的noderequire函数参数字符串。比如文件路径:’./app.js’(require(‘./app.js’));比如安装的npm模块:’lodash’(require(‘lodash’))。

value如果是数组,则数组中元素需要是上面描述的合理字符串值。数组中的文件一般是没有相互依赖关系的,但是又处于某些原因需要将它们打包在一起。

对于多入口,会建立彼此完全分离、互相独立的依赖图。

字符串entry:

img

数组entry:

img

字符串/字符串数组:

如果传入一个字符串或字符串数组,chunk 会被命名为 main

出口(output):

Output属性告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件,默认值为./dist。

可以存在多个入口,但只指定一个输出配置。

output.path只是指示输出的目录,对应一个绝对路径

明确chunk、bundle和module的概念

Webpack把每一个文件看成一个module,对入口module进行递归式打包,chunk是webpack的打包过程,是一堆module的集合,bundle是最终输出的打包文件。Chunk是过程量,bundle是结果量。

设定 HtmlWebpackPlugin

npm install --save-dev html-webpack-plugin

清理 /dist 文件夹

npm install clean-webpack-plugin –save-dev

注:在webpack-dev-server上运行,clean-webpack-plugin会把dist文件夹里面的内容全部清除,但webpack(build)的时候只会删除为使用的。

尝试补坑:https://blog.csdn.net/qq_44698161/article/details/102903521(注意clean 和 copy plugins使用的顺序)webpack打包顺序?

或者根据不同的环境配置使用clean-webpack-plugin

Loader:

Loader让webpack能够去处理那些非javascript文件(webpack自生只能理解javascript)。Loader可以将所有类型的文件转换成webpack能够处理的有效模块,再利用webpack进行打包。

在 webpack 的配置中 loader 有两个目标:

  1. test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
  2. use 属性,表示进行转换时,应该使用哪个 loader。

每个规则可以分为三部分 - 条件(condition),结果(result)和嵌套规则(nested rule)

Rule 条件

条件有两种输入值:

  1. resource:请求文件的绝对路径。它已经根据 resolve 规则解析。
  2. issuer: 被请求资源(requested the resource)的模块文件的绝对路径。是导入时的位置。

例如: 从 app.js 导入 ‘./style.css’,resource 是 /path/to/style.css. issuer 是 /path/to/app.js。

在规则中,属性 test, include, excluderesource 对 resource 匹配,并且属性 issuer(这个选项可以用来将 loader 应用到一个特定模块或一组模块的依赖中) 对 issuer 匹配。

当使用多个条件时,所有条件都匹配

Rule 结果

规则结果只在规则条件匹配时使用。

规则有两种输入值:

1. 应用的 loader:应用在 resource 上的 loader 数组。

  1. Parser 选项:用于为模块创建解析器的选项对象。

这些属性会影响 loader:loader, options, use

嵌套的 Rule

可以使用属性 rulesoneOf 指定嵌套规则。

这些规则用于在规则条件(rule condition)匹配时进行取值。

压缩和优化你的图像。查看 image-webpack-loader url-loader**,以了解更多关于如果增强加载处理图片功能。

插件(plugins)

插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

img

模式:

通过选择 developmentproduction 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

Devtool

此选项控制是否生成,以及如何生成 source map。

img

解析(resolve)

resolver 是一个库(library),用于帮助找到模块的绝对路径。一个模块可以作为另一个模块的依赖模块,然后被后者引用,如下:

import foo from 'path/to/module'

// 或者

require('path/to/module')
resolve.alias

创建 importrequire 的别名,来确保模块引入变得更简单,也可以在给定对象的键后的末尾添加 $,以表示精准匹配:

alias: {

 xyz$: path.resolve(__dirname, 'path/to/file.js')

}

这将产生以下结果:

import Test1 from 'xyz'; // 精确匹配,所以 path/to/file.js 被解析和导入

import Test2 from 'xyz/file.js'; // 非精确匹配,触发普通解析

resolve.extensions:

自动解析确定的扩展。默认值为:

extensions: [".js", ".json"]

能够使用户在引入模块时不带扩展:

import File from '../path/to/file'

resolve.modules

告诉 webpack 解析模块时应该搜索的目录。

开发中 Server(devServer)

npm install --save-dev webpack-dev-server

每次要编译代码时,手动运行 npm run build 就会变得很麻烦。webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码。webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。

webpack-dev-server主要是启动了一个使用express的Http服务器。它的作用主要是用来伺服资源文件。此外这个Http服务器和client使用了websocket通讯协议,原始文件作出改动后,webpack-dev-server会实时的编译,但是最后的编译的文件并没有输出到目标文件夹。

你启动**webpack-dev-server\后,你在目标文件夹中是看不到编译后的文件的**,\实时编译后的文件都保存到了内存当中。

webpack-dev-server支持2种自动刷新的方式:

1.Iframe mode

2.inline mode

compress: true//启用gzip压缩
contentBase: path.join(__dirname, "public")//告诉服务器从哪里提供内容
                    hot: true//启用热替换
                    lazy: true//dev-server只有在请求的时候才编译包
publicPath: "/assets/"          

HTML不会热更新。只有js,css这些被webpack管理的模块化东西才会热更新。

React Hot Loader:实时调整 react 组件

tree shaking

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 importexport

在一个纯粹的 ESM 模块世界中,识别出哪些文件有副作用很简单。然而,我们的项目无法达到这种纯度,所以,此时有必要向 webpack 的 compiler 提供提示哪些代码是“纯粹部分”。

这种方式是通过 package.json 的 “sideEffects” 属性来实现的。

{

 "name": "your-project",

 "sideEffects": false

}

(实验失败,了解)

生产环境配置

配置不同环境的webpack

npm install --save-dev webpack-merge

使用 merge,修改npm scripts

代码分离

代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。

有三种常用的代码分离方法:

· 入口起点:使用 entry 配置手动地分离代码。

如果入口 chunks 之间包含重复的模块,那些重复模块都会被引入到各个 bundle 中。

这种方法不够灵活,并且不能将核心应用程序逻辑进行动态拆分代码。

· 防止重复:

SplitChunks插件(webpack 4.x以前使用CommonsChunkPlugin)允许我们将公共依赖项提取到现有的entry chunk或全新的代码块中。

· 动态导入(懒加载):通过模块的内联函数调用来分离代码。

import()

import() 不同于 import,该方法为了动态加载模块而引入的新语法

import() 返回结果是 Promise

缓存

webpack 会生成一个可部署的 /dist 目录,然后把打包后的内容放置在此目录中。只要 /dist 目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问网站此服务器的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 缓存 的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快,然而,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。

输出文件的文件名(Output Filenames)

通过使用 output.filename 进行文件名替换,可以确保浏览器获取到修改后的文件。[hash] 替换可以用于在文件名中包含一个构建相关(build-specific)的 hash,但是更好的方式是使用 [chunkhash] 替换。


以上内容是以前练习使用webpack总结的,以后还会更新。


文章作者: 木叶勇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 木叶勇 !
 上一篇
经验-computed和do-while的使用 经验-computed和do-while的使用
computed和do-while的使用​ 这几天一直在改上次live上出的bug(在此表扬下写bug小能手),今天在测试的时候又遇到了一点问题,在此记录一下。 computed的使用​ 我们现在用的前端框架是KO(KnockO
2020-06-08
下一篇 
自动化构建工具-Gulp 自动化构建工具-Gulp
自动化构建工具-Gulp 在Javascript的开发过程中,经常会遇到一些重复性的任务,比如合并文件、压缩代码、检查语法错误、将Sass代码转成CSS代码等等。通常,我们需要使用不同的工具,来完成不同的任务,既重复劳动又非常耗时。grun
  目录