webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注构建模块化项目。
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
Webpack的工作方式是:会将项目当做一个整体,通过一个给定的主文件(如:index.js,入口文件),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
bundle:是由webpack打包出来的文件,
chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。
module:是开发中的单个模块,在webpack的世界,一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出所有依赖的模块。
loader:模块转换器,用于将模块的原内容按照需要转成你想要的内容
plugin:在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果,是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)。
模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。
devServer中通过hot属性可以设置模块的热替换。
new webpack.HotModuleReplacementPlugin(), //热加载插件
提高webpack的构建速度:
使用Happypack实现多线程加上编译。
几个常见的loader
- file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
- url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
- source-map-loader:加载额外的 Source Map 文件,以方便断点调试
- image-loader:加载并且压缩图片文件
- babel-loader:把 ES6 转换成 ES5
- css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
- style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
- eslint-loader:通过 ESLint 检查 JavaScript 代码
几个常见的plugin
- define-plugin:定义环境变量
- terser-webpack-plugin:通过TerserPlugin压缩ES6代码
- html-webpack-plugin 为html文件中引入的外部资源,可以生成创建html入口文件
- mini-css-extract-plugin:分离css文件
- clean-webpack-plugin:删除打包文件
- happypack:实现多线程加速编译
- html-webpack-plugin:会在打包结束后生成一个html文件,并把打包好的js文件引入到html中。可以用模板,new htmlWebpackPlugin({template:'./index.html'})
- clean-webpack-plugin:每次打包都清除之前的打包文件
- hash —— 即地址栏 URL 中的 # 符号。
比如 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
-
webpack中对于输出文件名可以有三种hash值: 1. hash 2. chunkhash 3. contenthash
-
hash: 每次修改任何一个文件,所有文件名的hash至都将改变(且都一样)。所以一旦修改了任何一个文件,整个项目的文件缓存都将失效。
-
chunkhash:根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,采用chunkhash的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。
-
contenthash:将样式作为模块import到JavaScript文件中的,所以它们的chunkhash是一致的。只要对应css或则js改变,与其关联的文件hash值也会改变,但其内容并没有改变呢,所以没有达到缓存意义。固contenthash的用途随之而来。contenthash是针对文件内容级别的,只有你自己模块的内容变了,那么hash值才改变。
-
sourceMap: 打包后的文件和开发的文件之间的映射,可以在module.expots={name:'development,devtool:'source-map' ,entry:{}},建议使用:cheap-module-eval-source-map 提示最全,打包速度最快的方式。在开发者模式下默认是打开的,如果上线,使用cheap-module-source-map
-
webpack-dev-server: 会自动打包,刷新浏览器,启动服务。打包的文件不是在配置的文件夹中,而是在内存中,可以提高打包速度。html没有生效,也不让浏览器自动刷新(例如:改变css),可以在devServer: hotOnly: true new webpack.HotModuleReplacementPlugin(), //热加载插件
-
babel: es转化器,=>官网安照说明操作,注意: 低版本浏览器可能对一些es6的语法不支持,可以用polyfill, 官网Docs->左侧菜单,在js中引入即可。
-
options: { presets:[['@babel/preset-env',{ useBuiltIns: 'usage'}]] 即可。
transform-runtime可以避免全局污染的方式,还需要安装runtime-corejs2 包。直接在根目录下新建babelrc文件即可。
-
进阶:tree shaking 只支持es 模块的引入(静态引入方法,import方式引入),引入模块的时候,要引入模块需要的,不引人所有的。 使用:在package.json中添加 ‘sideEffects':false(说明:对所有的莫都进行tree shaking,没有要进行特殊处理的,如果有,可以放一个数组) 配置文件中: optimization:{usedExports: true} 对于开发和生产环境配置文件有区别,可以分开做配置,例如:可以在package.json中直接 "dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js" 就可以区分开开发和生成。生产环境就可以删除一些不不要存在的代码了。可以把公用的代码拆分出来,最后利用webpack-merge合并。 -
代码分割 code splitting: 当页面逻辑发生变化时,就不会加载已缓存的,会减少访问时间的。在配置文件中: optimization: { splitChunks:{chunks:'all'}} 智能分割。
-
懒加载:import语法
-
eslint: npm i eslint -D 配置文件中:npm i eslint-loader -D
-