webpack :安装使用
以下记录使用关注点。(关于npm cli 不想看官网的可以看下个人之前的记录npm)
1.安装:官网建议本地安装,使用全局安装也可以
使用 Node.js 最新的长期支持版本(LTS - Long Term Support),是理想的起步。
npm install --save-dev webpack
npm install --save-dev webpack@<version>
如果你使用 webpack 4+ 版本,你还需要安装 CLI。
npm install --save-dev webpack-cli
体现测试版本:tag - beta
npm install webpack@beta
npm install webpack/webpack#<tagname/branchname>
执行 npx webpack
,会将我们的脚本作为入口起点,然后 输出 为 main.js
。Node 8.2+ 版本提供的 npx
命令,可以运行在初始安装的 webpack 包(package)的 webpack 二进制文件
npx webpack
2.配置
默认位置位于项目跟目录,另外在webpack bundle的入口文件中可以使用import 与 export
名称:webpack.config.js
打包命令,使用配置文件进行打包
npx webpack --config webpack.config.js
关于示例都是官网的示例,需要看的直接去官网。
加载其他资源:
使用loader 来配置加载器规则、一般loader 的命名都是通过文件类型-loader,比如css-loader,less-loader,file-loader等等
加载图片资源,本地资源通过file-loader 会一同输出到指定目录,那么css中的url指向也可以跟随更改,不用再自己挪移资源文件。
module: { rules: [ { test: /\.(css|less)$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ { loader: "file-loader" } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: "file-loader" } ] }, { test: /\.xml$/, use: [ 'xml-loader' ] } ] },
插件:干loader做不了的事情,记录一些常用插件
html-webpack-plugin
: 生成html,其中有很多选项配置,包括常用的title标签等等,建议是只针对入口文件的编译
clean-webpack-plugin
:清理文件,官网教程中的写法已经不可以了,现在已经更改,https://www.npmjs.com/package/clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const webpackConfig = { plugins: [ /** * All files inside webpack's output.path directory will be removed once, but the * directory itself will not be. If using webpack 4+'s default configuration, * everything under <PROJECT_DIR>/dist/ will be removed. * Use cleanOnceBeforeBuildPatterns to override this behavior. * * During rebuilds, all webpack assets that are not used anymore * will be removed automatically. * * See `Options and Defaults` for information */ new CleanWebpackPlugin(), ], }; module.exports = webpackConfig;
webpack-manifest-plugin:记录mainfest 追踪要点,一个json 用来追踪文件记录,生产一个资源manifest https://github.com/danethurber/webpack-manifest-plugin
{ "app.js": "app.bundle.js", "print.js": "print.bundle.js", "icon.png": "b167c98ad8d6884bc3585fdfaf898b7d.png", "index.html": "index.html" }
souce map 资源映射:打包后的js 映射会源代码
效果如下:
其他选项 https://www.webpackjs.com/configuration/devtool/
webpack 增强插件: source-map-loader
devtool: 'inline-source-map',
观察者模式:非常实用,也就是我们常说的自动编译
webpack --watch 命令
"watch": "webpack --watch",
其他工具:webpack-dev-server 模块,部署一个本地应用,自动监听config所在文件目录的文件。
https://www.npmjs.com/package/webpack-dev-server
安装完成后:
1、cli
webpack-dev-server
2、命令脚本
"scripts": { "start:dev": "webpack-dev-server" }
npm run start:dev
移除为引用代码 tree shaking
sideEffects
如果所有代码都不包含副作用,我们就可以简单地将该属性标记为 false
,来告知 webpack,它可以安全地删除未用到的 export 导出。
「副作用」的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。
排除:
{ "name": "your-project", "sideEffects": [ "./src/some-side-effectful-file.js" ] }
类似全局作用域定义的变量需要指定文件,否则不会引入,css 文件也是如此。
合并工具webpack-merge:
安装webpack merge 模块
npm install webpack-merge --save-dev
创建多个配置文件、使用merge:
const merge = require('webpack-merge'); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const common = require('./webpack.common.js'); // 合并 module.exports = merge(common, { mode: "production", devtool: 'source-map', plugins: [ new UglifyJSPlugin({ sourceMap: true }), new webpack.DefinePlugin({ 'process.env.NODE_ENV':JSON.stringify('production') }) ] });
定义执行脚本,指定打包配置:
"build": "webpack --config webpack.prod.js",
代码分离:
1.定义入口文件,在配置文件中定义多个entry(手动配置,多个模块引用会造成重复)
entry: { // 入口分类 // 键值为name占位符的名称 app: './src/index.js', // print: './src/print.js' },
2.使用模块分类 SplitChunksPlugin
https://webpack.js.org/plugins/split-chunks-plugin/
关于配置选项,到上面这个地址查看,此模块会把分类文件中引用相同的模块进行单独分类,避免造成重复。
config 配置文件增加优化属性optimization,这里我只加上了2个选项,chunks 代表指定哪些模块,有3个关键字all
,async
和initial
,也可以通过一个函数针对特性的一些模块进行分离
optimization: { splitChunks: { chunks: "all", automaticNameDelimiter:"-" } },
module.exports = { //... optimization: { splitChunks: { chunks (chunk) { // exclude `my-excluded-chunk` return chunk.name !== 'my-excluded-chunk'; } } } };
3.动态引入,分为2中
第一种通过es2015 import()语法,引入,返回的是一个promise,第二种是require.ensure
https://www.webpackjs.com/api/module-methods/#import-
使用import 需要搭配babel (原因就是一些地方不支持es6 语法)。因为是异步,可以使用async 函数配合,关于async,自行看阮一峰的es6。
懒加载:
动态执行import 加载所需模块。
顺表说一下es 的import 是引用,node 的require 是复制。
浏览器缓存-修改模块文件名称 chunkhash
。每次打包会计算散列值,如果文件内容修改,文件名亦改动。
注意在使用过程中,需要注释掉热部署吗,否则会报错。
output: { // filename: "bunlde.js", // name 占位符 filename: "[name].[chunkhash].js", path: path.resolve(__dirname, 'dist'), // 外网路径 publicPath: '/' },
使用HashedModuleIdsPlugin
,在重新打包后,针对公用提取的模块不会进行更改。
shimming : 针对不符合规范(AMD/COMMONJS/ES6 )比如Jquery ,会设置全局变量$ 这种。
另外,关于ployfill, 个人认为,永远不要自己写ployfill,想要做到兼容的话就去使用一些预编译器,别自己写,需要维护不说,可能还会有各种问题,测试也可能不到位,关键在于,有可能新的环境下,你的ployfill 会覆盖掉新版本中的新功能,
即便是自己,过不了多久也会忘记。
通过 webpack 编译的每个模块中,通过访问一个变量来获取到 package 包。如果 webpack 知道这个变量在某个模块中被使用了,那么 webpack 将在最终 bundle 中引入我们给定的 package。
与 tree shaking配合,导入loadsh 模块中的join 方法,删除无用的代码
join: ['lodash', 'join']
使用不在需要通过变量引入
element.innerHTML = join(['Hello', 'webpack'], ' ');
import-loader 与export-loader
复写this,全局this指向window
exports,改写export,针对以前的代码
var file = 'blah.txt'; var helpers = { test: function() { console.log('test something'); }, parse: function() { console.log('parse something'); } }
现在从我们的 entry 入口文件中(即 src/index.js
),我们能 import { file, parse } from './globals.js';
,然后一切将顺利进行。