webpack构建前端项目-前端webpack异步加载
1. 前端工程
前端工程是将前端开发工作带入一个更加系统化、规范化的体系的一系列过程。 这个过程包括源代码的预编译、模块处理和代码压缩。 工程将尽量保证开发者更友好的开发体验,保证源码质量和依赖的完整性; 工程部也会尽可能高效地将完成的代码交付给客户,以追求更好的用户体验。
为什么前端需要打包构建?
1)打包后体积可以更小(Tree-Shaking、压缩、合并)加载更快;
2)能够编译高级语言或语法(TypeScript、ES6+、SCSS、模块化);
3)兼容性和错误检查(Polyfill、postcss、ESLint)
常见的代码打包工具有Gulp、Grunt、Webpack等,不同的是Gulp和Grunt是自动化构建工具,打包的思路是:遍历源文件-匹配规则-打包,期间不能按需加载这个流程; Webpack 是一个静态资源打包工具,它从入口文件开始,通过 modules 依赖加载、解析和打包三个过程来完成项目的构建。 在加载、解析、打包三个过程中,可以有针对性地实现一些解决方案,达到按需加载的目的(比如拆分公共代码等)。
webpack 是一个模块打包器(例如 Browserify 或 Brunch)。 它不是任务运行程序(例如,Make、Grunt 或 Gulp)。 任务执行器用于自动化常见的开发任务,例如项目检查(lint)、构建(build)和测试(test)。 与捆绑器(bundler)相比,任务执行器关注的是更上层的问题。 另一方面,捆绑器可帮助您准备好 JavaScript 和样式表以供部署,并将它们转换为浏览器可用的格式。 例如,JavaScript 可以压缩、拆分块和延迟加载以提高性能。 打包是 Web 开发中最重要的挑战之一,解决它可以消除开发过程中的大部分痛点。
2. Webpack 基础
Webpack是一个可配置的模块打包工具webpack构建前端项目,可以通过修改Webpack配置文件(webpack.config.js)来进行配置。 此配置文件遵循 Node.js 的 CommonJS 模块规范。
// webpack.config.js示例
const path = require('path');
module.exports = {
mode: 'development',
entry: './foo.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'foo.bundle.js'
}
};
在上面的例子中,使用CommonJS require 导入Node.js 内置的路径模块,然后通过module.exports 导出Webpack 配置。
2.1 4个核心概念:entry output loader plugin
入口:项目入口。 如果是单页应用,可能只有一个入口; 如果它是一个多页面项目,那么通常一页会对应一个构建条目。
output:webpack的输出是指定编译打包入口对应的文件后的输出bundle。 常用属性path指定输出bundle的存放路径,如dist; filename 是包的名称; publicPath 指定浏览器中引用的URL地址,作为src或link指向文件。 当您需要将静态文件放在不同的域名或 CDN 上时webpack构建前端项目,这种方法很有用。
webpack从指定的入口文件(entry)开始,经过处理,最终根据output输出设置输出一个固定内容的bundle; 而这个处理过程使用了两个工具,loader和plugin——使用loader来处理多个 两种代码语言之间的转换,使用plugin扩展原有的模块打包过程:
1)加载器模块转换器:源代码的处理器,加载器是面向解决某个或某类模块的问题,通过加载器可以对文件本身的属性做一些相关的操作; (Webpack本身只能处理JavaScript,其他类型的语法我一窍不通,Loader可以理解为Webpack能力的扩展,如果我们需要引入某类模块,那么就需要增加一个特性type loader to it.) loader 允许 webpack 去处理那些非 JavaScript 文件(webpack 本身只懂 JavaScript)。 加载器可以将所有类型的文件转换成webpack可以处理的有效模块,然后你就可以使用webpack的打包能力来处理它们了。
2)Plugin extension:针对项目整体,解决loader无法处理的事情。 要使用插件,您只需 require() 并将其添加到 plugins 数组中。
比如模块转换器less-loader将less转换成css,扩展插件HtmlWebpackPlugin是一个可以将js和css插入到html文件中的插件。
2.2 3个重要概念:module chunks bundle
module-各个源代码文件是指通过import和require语句引入的代码,包括css、图片等资源;
chunk-多个模块组合,chunk是webpack根据功能拆分的,chunk包含模块,可以是一对多也可以是一对一。 chunk包括entry、import()、splitChunk三种代码拆分情况;
bundle - 最终输出文件。 Bundle就是webpack打包的各种文件。 一般与chunk(代码块)是一对一的关系。 Bundle是对chunk进行编译、压缩、打包后的输出。
2.3 Webpack基本使用:解析ES6、解析样式、解析图片文件。
分析ES6+主要是Babel。 具体使用介绍见:使用Babel转换JavasCript代码;
解析样式相关的加载器主要分为前处理器和后处理器加载器,参见:webpack基础配置-css样式相关加载器;
解析图片文件的主要loader有url-loader、file-loader、image-webpack-loader等,参见:webpack基础配置-管理项目中的静态资源
2.4 通常,webpack配置文件分为三个不同的配置文件:base general,dev开发环境,prod生产环境(为了复用和差异化,方便模块化)。 区分开发环境和生产环境的两套配置,各司其职。 比如在开发阶段,不需要压缩代码,压缩图片,计算hash,抽取CSS。 开发环境需要生成sourcemap文件,打印debug信息,热重载功能。
我们可以根据不同的环境将webpack的配置拆分成多个文件,在运行时直接根据环境变量加载对应的配置。 基本划分如下:
三、Webpack高级webpack代码拆分方法
拆分文件的目的是为了更好地利用缓存。 很大程度上,公共类库的分离是为了让多个页面使用缓存,从而减少下载代码量。 同时,使用缓存还有一个好处,可以减少代码变更时的代码下载量。
在Webpack中,一共提供了三种方式来实现代码拆分(Code Splitting):
入口配置:通过多个入口文件实现; 动态加载(on-demand loading):在编写代码时主动使用import()或require.ensure来动态加载; 提取公共代码:使用splitChunks配置提取公共代码。 webpack 优化构建速度——提升开发体验和效率
可用于生产环境:
1) 优化babel-loader;
2)忽略插件;
3)无解析;
4)快乐包;
5) 平行丑化插件;
不适用于生产环境,用于开发环境:
1)自动刷新;
2)热更新;
3) Dll插件
Webpack 优化输出代码——提升产品性能
1)小图片base64编码;
2)捆绑加哈希;
3)延迟加载;
4)提取公共代码;
5)使用CDN加速;
6) 忽略插件;
7)使用Production模式默认开启tree-shaking;
8) 范围托管;
本文引用参考资料:
05 基本概念和常用配置项介绍(一)-MOOC专栏第19篇使用Webpack的splitChunks功能拆分代码-MOOC专栏第12篇使用Webpack管理项目中的静态资源-MOOC专栏Webpack前端工程入门GITBOOK.CN gitbook.cn
理念 | webpack 中文站集成 | webpack中文网 使用webpack定制前端开发环境 juejin.im