Webpack 已经流行很长时间了。 很多人,尤其是刚进入web后端行业的新人,在使用webpack时还是一头雾水。 当他们看到这么多文档、各种配置、各种加载器和插件时webpack提取sass,他们立即感到困惑。 。 但如果我们想继续做好后端,webpack是一个必须克服的坎。 其实掌握webpack并不难,只是我们没有找到正确的方法。 让我带你学习webpack。
1.什么是webpack?
简而言之:webpack 是一个模块捆绑器。
重点是“模块”和“封装”两个关键词。 什么是模块? 我们回顾一下之前的后端开发方法。 JS文件是通过script标签静态引入的。 由于js文件之间没有强依赖关系,如果文件1想要使用文件2的个别技术或变量,则必须将文件1放在该文件中。 2 前置。 随着项目的缩小,js文件之间的依赖关系变得更加复杂,也更加难以维护。 这种困境驱使后端工程师不断探索新的开发模式。 我们从前端和应用程序开发模型中获得灵感。 为什么我们不能引入“模块”的概念,让js文件可以互相引用呢? 如果模块1想要使用模块2的功能,只需要在模块1中显式引用模块2即可,而不必担心它们的排列顺序。 基于这些理念,创建了 CommonJS 和 AMD 规范,然后出现了 require.js 和 system.js 等后端模块加载工具以及 Node 模块系统,直到今天流行的 es6 模块。
模块的引入解决了文件之间依赖引用的问题,而打包则解决了文件过多的问题。 当项目规模缩小、模块数量上千时,如果浏览器要加载这么多文件,页面加载速度必然受到影响,而bundler可以将多个相关文件打包在一起,从而大大减少文件负载。 该数字提高了网页加载性能。 提供模块化的开发方式和编译打包功能是webpack的核心,其他很多功能都是围绕着它们展开的。
2. 核心概念
1. 模块
对于webpack来说,模块不仅仅是一个javascript模块,它包括任何类型的源文件,无论是图片、字体、还是json文件,它们都是模块。 Webpack 支持以下形式的模块引用:
· ES2015导入方法
· CommonJs require() 方法
· AMD 定义和要求语法
· css/sass/less 文件中的 @import 语法
· url(...) 和
图像路径在
2. Dependency Graph(依赖图)
所谓依赖图,就是webpack根据各个模块之间的依赖关系,递归生成的内部逻辑图。 有了这个依赖图,webpack就可以根据该图将所有需要的模块打包到一个bundle文件中。
3. 入场
绘制依赖图的起始文件称为条目。 默认条目是./src/index.js,或者我们可以在配置文件中进行配置。 条目可以是一个或多个。
单次入境:
模块. 导出 = {
条目:'./src/index.js'
或者
模块. 导出 = {
入口: {
主要:'./src/index.js'
};
多个条目,一个块
我们还可以指定多个独立的文件作为条目,但将它们打包成一个块。 这种方法称为多主条目。 我们需要传入文件路径的链表:
模块. 导出 = {
条目:['./src/index.js', './src/index2.js', './src/index3.js']
但该修改方法的灵活性和可扩展性有限,因此不推荐。
多个条目,多个块
如果有多个entry,并且每个entry生成一个对应的chunk,我们需要传入object:
模块. 导出 = {
入口: {
应用程序:'./src/app.js',
管理员:'./src/admin.js'
};
这种写法具有最好的灵活性和扩展性,并且支持与其他部分配置合并。 例如,将开发环境和生产配置分离,提取公共配置,然后在不同环境中运行时将环境配置和公共配置合并。
4. 输出
有入口,就有相应的出口。 顾名思义,export就是webpack打包的输出,output定义了输出路径和文件名。 Webpack的默认输出路径是./dist/main.js。 同样,我们可以在配置文件中配置输出:
模块. 导出 = {
条目:'./src/index.js',
输出: {
路径:__dirname + '/dist',
文件名:'bundle.js'
};
多次入境的情况
当有多个条目时,一个条目应该对应一个输出。 这时需要使用替换的方式来声明输出文件名,以保证文件名的唯一性。 例如,使用入口模块的名称:
模块. 导出 = {
入口: {
应用程序:'./src/app.js',
搜索:'./src/search.js'
},
输出: {
文件名: '[名称].js',
路径:__dirname + '/dist'
最后会在./dist路径下生成两个bundle文件app.js和search.js。
5. 装载机
webpack本身只支持加载js和json模块,而webpack的思想是让所有文件都被引用加载并生成依赖图,所以loader就发挥了作用。 Loader 使 webpack 能够处理其他类型的文件(例如图像、字体文件、xml)。 我们可以在配置文件中定义一个加载器,如下所示:
webpack.config.js
模块. 导出 = {
模块: {
规则:[
测试:/.txt$/,
使用:'原始加载程序'
};
其中,test定义了需要转换的文件或文件类型,use定义了转换文件的loader的类型。 这个配置相当于告诉webpack,当遇到对txt文件的引用时(使用require或import进行引用),首先使用raw-loader转换该文件,然后将其打包到bundle中。
还有其他类型的loader,比如加载css文件的css-loader、加载图片和字体文件的file-loader、加载html文件的html-loader、将最新的JS句型转换成ES5的babel-loader等。 。 请参阅 webpack 加载器以获取完整列表。
6. 插件
插件和加载器是两个令人困惑且模糊的概念。 Loader用于转换和加载特定类型的文件,因此loader的执行级别是单个源文件。 该插件可以实现的功能更加强大。 该插件可以监听webpack处理过程中的关键事件,并深度集成到webpack编译器中。 可以说插件的执行层面就是整个创建过程。 Plugin 系统是 webpack 的支柱。 Webpack 本身也是建立在插件系统之上的。 Webpack拥有丰富的外部插件和外部插件,并且允许用户自定义插件。 官方列出的插件包括这些。
与loader不同的是,要使用plugin我们首先要引用plugin,例如:
const webpack = require('webpack'); // 用于引用webpack外部插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 外部插件
模块. 导出 = {
插件:[
新的 webpack.HotModuleReplacementPlugin(),
新的 HtmlWebpackPlugin({模板: './src/index.html'})
};
3. 练习
了解了webpack的基本概念之后,我们就可以通过实践来加深理解。 接下来,我们使用webpack构建一个简单的react脚手架。
1. 创建项目
首先创建react-webpack-starter项目并使用npm init对其进行初始化。
2.安装依赖
安装反应
npm 我反应反应-dom
webpack相关的安装
npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin 样式加载器 css-loader
安装webpack-cli后,可以在命令行执行webpack命令; webpack-dev-server 提供了一个简单的 Web 服务器,并且更改文件后可以手动执行 webpack 编译操作并手动刷新浏览器,消除重复的自动操作。 ; html-webpack-plugin用于手动生成index.html文件webpack提取sass,并在index.html中手动添加对bundle文件的引用; style-loader 和 css-loader 用于加载 css 文件。
babel相关安装
由于react使用的是class、import等es6句型,为了提高网站的浏览器兼容性,我们需要使用babel进行转换。
npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
其中@babel/core是babel的核心模块,包含了babel的核心功能; @babel/preset-env 支持 ES6 和更新的 js 句型的转换,并且可以根据需要兼容的浏览器类型选择加载的插件,从而简化生成代码; @babel/preset-react 包含babel转换react所需的插件; babel-loader 是 webpack 的 babel 加载器。
3.配置webpack
在项目根目录下新建webpack.config.js,内容如下:
webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /.js$/, exclude: /node_module/, use: 'babel-loader' }, { test: /.css$/, use: ['style-loader', 'css-loader'] // 注意排列顺序,执行顺序与排列顺序相反 } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ] }
其中,HtmlWebpackPlugin使用自定义模板来生成html文件。 模板内容如下:
./src/index.html
My React App
配置巴贝尔
在项目根目录下新建.babelrc文件,配置我们安装的两个babel预设:
.babelrc
“预设”:[
“@babel/preset-env”,
“@babel/预设反应”
生成react应用程序根节点
./src/索引
从“反应”导入反应;
从'react-dom'导入ReactDOM;
从“./components/App”导入应用程序;
ReactDOM.render(, document.getElementById('app'));
./src/component/App.js
从 'react' 导入 React, { Component };
导入'./App.css';
导出默认类 App 扩展 Component {
使成为() {
返回 (
我的 React webpack 启动器
./src/components/App.css
身体{
字体大小:60px;
字体粗细:加粗;
红色;
文本转换:大写;
4.配置package.json
最后,在 package.json 文件中添加两个脚本来运行开发服务器和包:
包.json
“脚本”:{
"start": "webpack-dev-server --modedevelopment --open --hot",
"build": "webpack --模式生产"
注意,我们启用了 webpack-dev-server 的热模块更新功能(HMR),以进一步提高我们的开发效率。
至此,最简单版本的react脚手架就完成了。 我们运行一下看看效果: