点错了 直接发布了 千万别说没写完 后续会更新的
webpack 基本 文档梳理
概念
webpack :一个现代 JavaScript 应用程序的静态模块打包器(module bundler)
- 入口(entry): webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的
- 输出(output): 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件
- loader: 用于对模块的源代码进行转换,让 webpack 能够去处理那些非 JavaScript 文件
- 插件(plugins): 用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
- 模式(mode): 开发环境还是生产环境
- 模块解析(resolver): 帮助找到弄快的绝对路径。
- 构建目标(targets): node环境还是浏览器环境
- 模块热替换(HMR): 在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面
多种配置类型
- 导出一个函数 : 运用在开发和生产构建区别之间,用webpack-merge 合并
- 导出一个 Promise : 需要异步地加载所需的配置变量,例如:动态加载文件路径等
- 导出 多个配置对象: 例如node环境 和 web环境 分开配置
webpack的基本功能和工作原理
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
- 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
- 模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
- 自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
- 代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
webpack构建过程
- 从entry里配置的module开始递归解析entry依赖的所有module
- 每找到一个module,就会根据配置的loader去找对应的转换规则
- 对module进行转换后,再解析出当前module依赖的module
- 这些模块会以entry为单位分组,一个entry和其所有依赖的module被分到一个组Chunk
- 最后webpack会把所有Chunk转换成文件输出
- 在整个流程中webpack会在恰当的时机执行plugin里定义的逻辑
webpack
- webpack-bundle-analyzer webpack打包后 bundle大小分析
- webpack-merge 用于合并webpack的公共配置和环境配置(合并webpack.config.js和webpack.development.js或者webpack.production.js)
- ProgressBarWebpackPlugin 打包编译的时候以进度条的形式反馈打包进度
常用loader
- url-loader 可将文件转换为base64 URIs
- file-loader 将文件发送到输出文件夹,并返回(相对)URL
- ts-loader 或 awesome-typescript-loader 像 JavaScript 一样加载 TypeScript 2.0+
- babel-loader 加载 ES2015+ 代码,然后使用 Babel 转译为 ES5
- html-loader 导出 HTML 为字符串,需要引用静态资源
- xml-loader 加载XML文件
- markdown-loader 使用markmark的webpack的markdown-loader
- style-loader 将模块的导出作为样式添加到 DOM 中
- css-loader 解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
- less-loader 加载和转译 LESS 文件
- sass-loader 加载和转译 SASS/SCSS 文件
- postcss-loader 使用 PostCSS 加载和转译 CSS/SSS 文件
- stylus-loader 加载和转译 Stylus 文件
- eslint-loader PreLoader,使用 ESLint 清理代码
- mocha-loader 使用 mocha 测试(浏览器/NodeJS)
- postcss-safe-parser PostCSS的容错CSS解析器,它将查找并修复语法错误,能够解析任何输入
常用 plugins (npm 官网可以自己找连接 这里以后再把连接加上)
- ExtractTextWebpackPlugin 从 bundle 中提取文本(CSS)到单独的文件
- HtmlWebpackPlugin 简单创建 HTML 文件,用于服务器访问
- CleanWebpackPlugin用于清除本地文件,在进行生产环境打包的时候,如果不清除dist文件夹,那么每次打包都会生成不同的js文件或者css文件堆积在文件夹中,因为每次打包都会生成不同的hash值导致每次打包生成的文件名与上次打包不一样不会覆盖上次打包留下来的文件
- MiniCssExtractPlugin webpack打包样式文件中的默认会把样式文件代码打包到bundle.js中,MiniCssExtractPlugin这个插件可以将样式文件从bundle.js抽离出来一个文件,并且支持chunk css
- UglifyjsWebpackPlugin 可以控制项目中 UglifyJS 的版本
- OptimizeCssAssetsWebpackPlugin css压缩,主要使用 cssnano 压缩器(webpack4的执行环境内置了cssnano,所以不用安装)
- SplitChunksPlugin CommonChunkPlugin 的后世,用于对bundle.js进行chunk切割(webpack的内置插件)
- DllPlugin 为了极大减少构建时间,进行分离打包
- DllReferencePlugin 将预先编译好的模块关联到当前编译中,当 webpack 解析到这些模块时,会直接使用预先编译好的模块(webpack的内置插件)
- DefinePlugin 允许在编译时(compile time)配置的全局常量
- HotModuleReplacementPlugin 启用模块热替换(Enable Hot Module Replacement - HMR)
- HardSourceWebpackPlugin 为模块提供中间缓存步骤,加快后续构建速度
- babel-plugin-import-fix 缩小引用范围
babel
- babel-core babel核心编译包
- babel-loader 使用Babel和webpack转换JavaScript文件
- babel-plugin-import 用于babel的模块化导入插件按需加载,例如antd、lodash
- @babel/plugin-proposal-decorators decorators编译
- babel-plugin-transform-export-extensions es6导出语法
- babel-plugin-transform-react-jsx 将JSX变成React函数调用
- babel-plugin-transform-runtime 提供es6代码运行环境,常在第三方运行类库中使用
- @babel/polyfill es6运行环境,常在项目中使用
- babel-plugin-ramda ramda 的 tree-shaking
- babel-plugin-lodash tree-shaking代码
- babel-plugin-react-docgen-typescript ts文档自动提示
其他常用 node package
- chalk 给命令行中的文字添加样式
- commander 编写node命令行,cli必备
- cross-spawn nodejs spawn 的跨平台的版本。主要用来创建子进程执行一些命令
- fs-extra 提供对文件操作的方法
- current-git-branch 获取当前分支名称
- validate-commit-msg 验证git commit规范
react 常用 项目依赖 package
- antd ui组件库
- classnames 动态合并 className
- clipboard 复制粘贴
- dva 阿里出品,基于 redux 和 redux-saga 的数据流方案
- dva-loading 自动加载dva的数据绑定插件,不用再写showLoading and hideLoading
- dva-model-extend 扩展dva模型的实用方法,类似对象合并
- immutable Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象,可以避免deepCopy带来的性能消耗
- jsonwebtoken 前端token加密
- moment Date对象操作
- shortid 生成唯一key,常用在数组和map对象,对数据辨别去重等操作
- @mdx-js/tag 根据Markdown语法将组件映射到HTML元素
- ramda JavaScript 函数库
- transform-react-remove-prop-types 在production 删除 prop types 代码
react 常用 开发依赖 package
- react-hot-loader 保留react组件状态的同时热加载局部更新,依赖 webpack 的 HotModuleReplacement 热加载插件
- react-docgen-typescript react ts文档提示
- react-dev-utils create-react-app 提供的公共模块
webpack bundle 优化
Tree-shaking
- 用于描述移除 JavaScript 上下文中的未引用代码(dead-code)
- Tree-shaking 在production环境使用,要开启package.json中
{sideEffects:true} - Tree-shaking 只能消除没有被引用的变量和函数,不能消除类
- ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析。 Tree-shaking以此作为基础区分
实践
- babel-plugin-import —— 按需引入 点击进入antd官网说明
{
plugins: [
["import",
{ "libraryName": "antd", 'libraryDirectory': 'es', "style": true }
]
]
}
- babel-plugin-ramda —— ramda Tree Shake
{
plugins: [
["ramda", {
"useES": true
}]
,
}
- webpack bundle文件去重
todo 等一下 自己研究一下 下面两个配置的区别
{
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "commons",
}),
new webpack.optimize.CommonsChunkPlugin({
children: true,
async: true,
minChunks: 2, // the least number of chunks reusing a module before module can be exported
}),
]
}

Code split
- 入口起点:使用 entry 配置手动地分离代码。
- 防止重复:使用 CommonsChunkPlugin 去重和分离 chunk
- 动态导入:通过模块的内联函数调用来分离代码
lazy-load
开发速度和打包优化
hmr 与 hot-loader
happypack
hardsource
bundle-analyzer
css minimize
transform-react-remove-prop-types
{
"presets": [["es2015", { "modules": false }], "stage-2", "react"],
"env": {
"production": {
"plugins": ["transform-react-remove-prop-types"]
}
}
}