Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
步骤:
引入各种外部资源文件(module)--->生成chunk(代码块)--->利用load和plugin 解析chunk中相对应的代码,生成webpack可识别的js代码 --->打包生成bundle
在这里引入Module、Chunk和Bundle的概念,上面代码中也经常会看到有这两个名词的出现,那么他们三者到底有什么区别呢?首先我们发现module是经常出现在我们的代码中,比如module.exports;而Chunk经常和entry一起出现,Bundle总是和output一起出现。
- module:我们写的源码,无论是commonjs还是amdjs,都可以理解为一个个的module
- chunk:当我们写的module源文件传到webpack进行打包时,webpack会根据文件引用关系生成chunk文件,webpack 会对这些chunk文件进行一些操作
- bundle:webpack处理好chunk文件后,最后会输出bundle文件,这个bundle文件包含了经过加载和编译的最终源文件,所以它可以直接在浏览器中运行。
通过下面一张图更深入的理解这三个概念:
了解webpack,首先得熟悉webpack四个核心概念:
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
1.入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
例子:
webpack.config.js
module.exports = { entry: './path/to/my/entry/file.js' };
2.出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output
字段,来配置这些处理过程:
如果是单个入口文件,可以如下配置
const path = require('path'); module.exports = { entry: 'app.js', output: { path: path.resolve(__dirname, 'dist'), filename: '、bundle.js' } };
多个入口起点
如果配置创建了多个单独的 "chunk"(例如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用占位符(substitutions)来确保每个文件具有唯一的名称。
{ entry: { app: './src/app.js', search: './src/search.js' }, output: { filename: '[name].js', path: __dirname + '/dist' } }
以下是使用 CDN 和资源 hash 的复杂示例:
const path = require('path'); output: { filename:'[name].js' path:path.resolve( __dirname + '/dist'), publicPath: "http://cdn.example.com/assets/" }
生成的页面中引入的js如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>project-template</title> <link rel="shortcut icon" type="image/x-icon" href="./static/favicon.ico" /> </head> <body> <div id="app"></div> <script src="https://cdn.example.com/assets/example.js"></script> </body> </html>
publicpath:
其实这里说的所有资源的基础路径是指项目中引用css,js,img等资源时候的一个基础路径,这个基础路径要配合具体资源中指定的路径使用,所以其实打包后资源的访问路径可以用如下公式表示:
静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径
output.publicPath = '/dist/' // image options: { name: 'img/[name].[ext]?[hash]' } // 最终图片的访问路径为 output.publicPath + 'img/[name].[ext]?[hash]' = '/dist/img/[name].[ext]?[hash]' // js output.filename output: { filename: '[name].js' } // 最终js的访问路径为 output.publicPath + '[name].js' = '/dist/[name].js' // extract-text-webpack-plugin css new ExtractTextPlugin({ filename: 'style.[chunkhash].css' }) // 最终css的访问路径为 output.publicPath + 'style.[chunkhash].css' = '/dist/style.[chunkhash].css'
Loader:
loader 用于对模块的源代码进行转换。loader 可以使你在 import
或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import
CSS文件!
通俗的讲就是loader能把各种webpack识别的文件转化成webpack能识别的js文件(webpack本身只能识别js文件)
Plugin:
Plugin的功能更加的强大,其目的在于解决 loader 无法实现的其他事。包括打包,压缩,改变环境变量等
mode:
提供 mode
配置选项,告知 webpack 使用相应模式的内置优化。