《Webpack原理与实践》课程之如何使用Webpack实现模块化打包

·  阅读 172

打包概述

Webpack 作为一个模块化打包工具,除了能实现模块化打包的问题,还能在打包过程中通过 Loader 机制编译代码解决兼容性问题以及不同类型的文件(如 css 图片 html等)的打包编译问题,另外,还具备代码拆分能力,将应用中所有的模块按需分块打包,不用担心全部的代码打包到一起,产生单个文件过大,导致加载慢的问题。

Webpack 把应用初次加载所必须要用的模块打包到一起,其他的模块再单独打包,后续应用在运行过程中实际需要用到哪个模块再异步加载对应的包,实现增量加载(渐进式加载)。

安装

webpack 本身就是 npm 的工具模块,因此,可以用 npm 安装 webpack 相关的包

npm init --yes // 初始化一个 package.json 文件,管理依赖包的版本
npm i webpack webpack-cli --save-dev
复制代码

webpackWebpack 的核心模块 webpack-cliWebpackCLI 程序,用来在命令行中调用 webpack webpack-cli 所提供的命令行程序存放在 node_modules/.bin 当中

默认情况下,打包入口是 src/index.js ,打包好的文件放到 dist/main.js 中。

配置webpack

在项目根目录下添加文件 webpack.config.js ,这个 js 是运行在 Node.js 的环境中,因此需要用到 require exports 来导入和导出模块。下面通过 Webpack配置来了解 Webpack 的四个重要的概念:

const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装插件
const webpack = require('webpack'); //访问内置的插件
const path = require('path')

module.exports = {
	entry: './src/main.js', // 概念1:入口。项目打包的入口文件,其中 `./` 不能省
	output: { // 概念2:出口。
		filename: 'bundle.js', // 输出文件的文件名称
		path: path.join(__dirname, 'output') // 输出文件的路径,即打包之后的文件放在哪里。__dirname 是 Node.js 的内置模块
	},
        module:{
            rules: [
              { test: /\.css$/, use: 'css-loader' },
              { test: /\.ts$/, use: 'ts-loader' }
            ] // loader 加载编译非js文件
        }
        plugins: [
            new webpack.optimize.UglifyJsPlugin(),
            new HtmlWebpackPlugin({template: './src/index.html'})
        ] // 增强自动化构建能力
}
复制代码

Webpack工作模式

  • production 模式下,启动内置优化插件,自动优化打包结果,打包速度偏慢,默认的打包方式
  • development 模式下,自动优化打包速度,添加一些调试过程中的辅助插件以便于更好的调试错误
  • none 模式下,进行最原始的打包,不做任何额外处理,一般需要分析我们模块的打包结果时会用到

修改打包模式的方式:通过 CLI --mode 参数传入,或者在 webpack.config.js 中配置 mode 属性

分析bundle.js,理解Webpack打包原理(none模式)

// 打包成了一个立即执行函数
(function(modules){ // modules表示项目中需要打包的所有模块
	var installedModules = {} // 缓存加载过的模块,提高打包效率
	function __webpack_require__(moduleId){} // 用于加载指定模块的函数
	// 挂载一些其他的数据和工具函数
	__webpack_require__.m = modules // 暴露模块
	__webpack_require__.c = installedModules // 暴露模块缓存
	__webpack_require__.d = function(exports, name, getters){} // 定义出口的获取方法
	__webpack_require__.r = function(exports) // 定义__esModule到出口上
	......
	return __webpack_require__(__webpack_require__.s = 0) // 开始加载源代码中的入口文件并返回出口,模块id为0
})([
	(function(module, __webpack_exports__, __webpack_require__){}), // 一个函数对应一个模块
	(function(module, __webpack_exports__, __webpack_require__){
 })
])
复制代码

具体的打包原理还是需要自己在浏览器中对 bundle.js 进行打断点,一点一点看它具体做了什么。

分类:
前端
标签: