文章目录
模块化介绍
模块化是指把⼀个复杂的系统分解到多个模块以⽅便编码。
CommonJS
CommonJS 是⼀种使⽤⼴泛的 JavaScript 模块化规范,核⼼思想是通过 require ⽅法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接⼝。 CommonJS 规范的流⾏得益于 Node.js 采⽤了这种⽅式,后来这种⽅式被引⼊到了⽹⻚开发中。
采⽤ CommonJS 导⼊及导出时的代码如下:
// 导⼊
const moduleA = require('./moduleA');
// 导出
module.exports = moduleA.someFunc;
AMD
AMD 也是⼀种 JavaScript 模块化规范,与 CommonJS 最⼤的不同在于它采⽤异步的⽅式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs。
采⽤ AMD 导⼊及导出时的代码如下:
// 定义⼀个模块
define('module', ['dep'], function(dep) {
return exports;
});
// 导⼊和使⽤
require(['module'], function(module) { });
ES6模块化
ES6 模块化它在语⾔的层⾯上实现了模块化。浏览器⼚商和 Node.js 都宣布要原⽣⽀持该规范。它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通⽤的模块解决⽅案。
采⽤ ES6 模块化导⼊及导出时的代码如下:
// 导⼊
import { readFile } from 'fs';
import React from 'react';
// 导出
export function hello() {};
export default {
// ...
};
ES6模块虽然是终极模块化⽅案,但它的缺点在于⽬前⽆法直接运⾏在⼤部分 JavaScript 运⾏环境下,必须通过⼯具转换成标准的 ES5 后才能正常运⾏。
样式文件中的模块化
除了 JavaScript 开始模块化改造,前端开发⾥的样式⽂件也⽀持模块化。 以 SCSS 为例,把⼀些常⽤的样式⽚段放进⼀个通⽤的⽂件⾥,再在另⼀个⽂件⾥通过 @import 语句去导⼊和使⽤这些样式⽚段。
新框架
- React 框架引⼊ JSX 语法到 JavaScript 语⾔层⾯中,以更灵活地控制视图的渲染逻辑。
- Vue 框架把⼀个组件相关的 HTML 模版、JavaScript 逻辑代码、CSS 样式代码都写在⼀个⽂件⾥,这⾮常直观。
Webpack初步
随着Web应用的日益复杂化,相关开发技术如同春日里的百花争艳,竞相绽放。这一趋势对前端构建工具提出了更为严苛的要求。在众多构建工具中,Webpack以其卓越的性能和灵活性脱颖而出,成为当前最为流行且不可或缺的前端构建工具之一。它几乎已经成为每一位追求前沿技术的前端工程师必备的技能之一。因此,紧跟行业步伐的前端工程师们,掌握Webpack已成为提升工作效率、优化项目开发的必修课。
Webpack环境配置
-
安装到全局
npm i -g webpack npm i -g webpack-cli
-
查看版本
webpack -v
-
安装依赖
这一步需要我们打开我们的vscode,打开我们的项目里的终端,输入以下👇命令:npm init
然后就会出现一个
package.json
描述文件 -
安装webpack到项目当中
npm i -D webpack npm i -D webpack-cli
-
使用Webapck
-
创建一个
public
文件夹,主要放置主入口文件 -
再创建一个
webpack.config.js
文件 -
在
webpack.config.js
文件书写代码const path = require("path"); module.exports={ //入口 entry:"引用文件路径", //把所有依赖的模块合并并输出到一个"输出文件的文件名.格式"文件中 output:{ filename:"输出文件的文件名.格式", path:path.resolve(__dirname,"输出路径"), } }
-
-
运行Webpack进行打包,只需要在终端输入
webpack
即可运行。 -
在入口文件
index.html
引入输出的打包文件
,就可以查看运行效果。
使用Loader
Loader是一个重要点,是webpack的核心概念之一。我们在使用webpack一定要知道一切皆模块
。那么所有的内容都必须要经过webpack进行处理,不过是图片还是CSS文件,并不是随便引入就能直接运行的。
如果要支持非JS类型的键,需要使用Webpack的Loader机制。Webpack的配置修改使用如下:(我们这里已添加Css文件为例)
-
安装CSS依赖
npm i -D style-loader css-loader
-
修改
webpack.config.js
配置文件module:{ //配置很多你需要处理的方案 rules:[ { //test:⽤正则去匹配要⽤该转换的 CSS ⽂件 test: /\.css$/, //使用Loader插件进行处理 use:["style-loader","css-loader"] } ] }
配置一个webpack快捷启动方案:
打开
package.json
然后输入
"起一个看名字"="webpack"
使用plugin
Plugin 是⽤来扩展 Webpack 功能的,是Webpack的核心特性之一,它们被用来扩展Webpack的功能。Webpack自身只负责打包模块,而插件则可以用来处理各种各样的任务,从打包优化和资源管理到环境变量注入等。
-
安装插件:首先,需要通过npm或yarn来安装所需的插件。
npm install --save-dev plugin-name
-
配置插件:在
webpack.config.js
文件中,通过在plugins
数组中添加一个新的插件实例来配置插件。const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件 module.exports = { // ...其他配置... plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' // 插件配置 }), // ...其他插件... ], };
-
运行Webpack:配置完成后,运行Webpack进行构建,插件就会在构建过程中执行其功能。
下面我简单举两个常用的插件进行讲解。
分离css和js插件
- 安装插件依赖
npm install --save-dev optimize-css-assets-webpack-plugin
npm install --save-dev mini-css-extract-plugin
-
配置加载文件
在上⼀节中通过 Loader 加载了 CSS ⽂件,本节将通过 Plugin 把注⼊到 bundle.js ⽂件⾥的 CSS 提取到单独的
⽂件中,配置修改如下:
const path = require('path'); // 压缩CSS代码 const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); // 分离CSS代码 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { // JavaScript 执行入口文件 entry: './src/index.js', output: { // 把所有依赖的模块合并输出到一个 bundle.js 文件 filename: 'bundle.js', // 输出文件都放到 dist 目录下 path: path.resolve(__dirname, './dist'), }, module: { rules: [ { // 用正则去匹配要用该 loader 转换的 CSS 文件 test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, }, "css-loader", ], }, ], }, plugins: [ // css代码压缩 new OptimizeCssAssetsPlugin(), // 单独提取CSS文件 new MiniCssExtractPlugin({ filename: "main.css", chunkFilename: "[id].css", }), ], };
分离html文件插件
经过了上面的文件分离,此时我们的⽂件是放⼊在dist⽂件夹中,但是dist本事是动态⽣成的⽣产环境,所以。我们此时创建public⽂件夹,然后配置HTML⽂件分离。
-
安装依赖
创建public⽂件夹,然后移动index.html到public⽂件夹中npm install -D html-webpack-plugin
-
修改配置⽂件
const HTMLPlugin = require('html-webpack-plugin') plugins: [ new HTMLPlugin({ template: './public/index.html' }) ]
使用DevServer
前⾯的⼏节只是让 Webpack 正常运⾏起来了,但在实际开发中你可能会需要在服务器运行,所以本节就来讲解如何在服务器端进行运行。
-
安装一个依赖
npm install -D webpack-dev-server
-
增加一些关于服务器的配置
devServer:{ //服务器打开目录 contentBase:path.join(__dirname,"默认打开的文件夹名称") //是否需要压缩 compress:true, port:8080, //选择端口号 hot:ture, //是否热更新,就是对代码的修改会进行监听,会自动更新浏览器 open:true //自动打开浏览器 }
-
修改package.json文件
"dev": "webpack-dev-server --config webpack.config.js"
-
运行命令
npm run dev
配置一个运行命令快捷执行方式:
同样的打开
package.json
最后输出的命令就不一样了🥳
更多配置
通过前面的学习,我们已经对Webpack有了初步的认识,虽然Webpack功能强大、内容复杂,但是只要你理解了其中的几个核心概念,就能得心应手的使用它。
下面来介绍以下Webpack的几个核心概念:
- Entry:⼊⼝,Webpack 执⾏构建的第⼀步将从 Entry 开始,可抽象成输⼊。
- Module:模块,在 Webpack ⾥⼀切皆模块,⼀个模块对应着⼀个⽂件。Webpack 会从配置的 Entry 开
- 始递归找出所有依赖的模块。
- Chunk:代码块,⼀个 Chunk 由多个模块组合⽽成,⽤于代码合并与分割。
- Loader:模块转换器,⽤于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注⼊扩展逻辑来改变构建结果或做你想要的事
- 情。
- Output:输出结果,在 Webpack 经过⼀系列处理并得出最终想要的代码后输出结果。
entry配置
entry是配置模块的⼊⼝,可抽象成输⼊,Webpack 执⾏构建的第⼀步将从⼊⼝开始搜寻及递归解析出所有⼊⼝依赖的模块。
- entry 配置是必填的,若不填则将导致 Webpack 报错退出。
例如,在⼀个项⽬中,可以存在多个⼊⼝地址,此时可以在entry中配置。增加其他⼊⼝⽂件dist/login.html和src/login/login.js
修改输出文件
entry: {
index: "./src/index.js",
login: "./src/login/login.js"
},
// 模式区分:⽣产和开发环境
mode: 'development',
output: {
// 把所有依赖的模块合并输出到⼀个 bundle.js ⽂件
filename: '[name].js',
// 输出⽂件都放到 dist ⽬录下
path: path.resolve(__dirname, './dist'),
}
运⾏代码之后,我们可以访问两个⼊⼝,在login的路径中可以看到打印:
http://localhost:9000
http://localhost:9000/login
Resolve配置
Webpack 在启动后会从配置的⼊⼝模块出发找出所有依赖的模块,Resolve 配置 Webpack 如何寻找模块所对应的⽂件。 Webpack 内置 JavaScript 模块化语法解析功能,默认会采⽤模块化标准⾥约定好的规则去寻找,但你也可以根据⾃⼰的需要修改默认的规则。
resolve下⾯有很多配置,我们这⾥介绍⼀个简单的,取消添加后缀:
resolve: {
extensions: ['.js', '.json']
},
Vue环境配置
Vue 是一个灵活轻量的MVVM框架,与React和Angular相比,它提供了渐进式的功能集成。Vue不强加特定的功能和语法,允许开发者根据项目需求逐步添加所需功能。尽管Vue项目可以直接在浏览器环境中运行,但为了提高编码效率,大多数项目都倾向于使用Vue官方推荐的单文件组件(.vue文件)格式进行开发。本书将重点介绍如何利用Webpack来构建Vue单文件组件,而不是传统的直接引用Vue的方式,后者虽然经典但已较为过时。
-
接下来我们配置⼀下相关环境 css预处理器
npm i -D stylus stylus-loader npm i -D postcss-loader
-
预处理器⼯具
npm i -D autoprefixer
-
处理html⽂件
npm i -D html-webpack-plugin
-
处理vue⽂件
npm i -D vue vue-loader vue-style-loader vue-template-loader vue-templatecompiler
-
-
修改webpack.config.js⽂件
const path = require('path'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const HTMLPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); module.exports = { // JavaScript 执行入口文件 entry: { index: "./src/index.js", login: "./src/login/login.js", }, // 模式区分:生产和开发环境 mode: 'development', output: { // 把所有依赖的模块合并输出到一个 [name].js 文件 filename: '[name].js', // 输出文件都放到 dist 目录下 path: path.resolve(__dirname, './dist'), }, module: { rules: [ { // 用正则去匹配要用该 loader 转换的 CSS 文件 test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, }, "css-loader", ], }, { test: /\.js$/, use: ['babel-loader'], include: path.resolve(__dirname, 'src'), }, { test: /\.vue$/, use: { loader: 'vue-loader', }, }, { test: /\.styl/, use: [ 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader', ], }, ], }, plugins: [ // css代码压缩 new OptimizeCssAssetsPlugin(), // 单独提取CSS文件 new MiniCssExtractPlugin({ filename: "main.css", chunkFilename: "[id].css", }), new VueLoaderPlugin(), new HTMLPlugin({ filename: './public/index.html', template: './public/index.html', }), new webpack.HotModuleReplacementPlugin(), ], devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, port: 9000, hot: true, open: true, }, resolve: { extensions: ['.js', '.json'], }, };
-
修改主⼊⼝⽂件index.js如下
import "../assets/css/main.css" import Vue from 'vue'; import App from './components/hello.vue'; new Vue({ el: '#root', render: h => h(App) });
-
复制index.html⼊⼝⽂件到public/index.html
-
同时需要处理css,在项⽬根⽬录下创建postcss.config.js
const autoprefixer = require('autoprefixer') module.exports = { plugins:[ autoprefixer() ] }
React框架配置
接下来我们构建⼀个React基础环境,在React中我们需要解决的jsx语法问题。
-
安装依赖
npm install -D @babel/preset-react npm install -S react npm install -S react-dom
-
在配置⽂件中,我们也需要添加jsx语法的解析
{ //⼀个匹配loaders所处理的⽂件的拓展名的正则表达式,这⾥⽤来匹配js和jsx⽂件(必须) test: /\.(js|jsx)$/, //屏蔽不需要处理的⽂件(⽂件夹)(可选) exclude: /node_modules/, //loader的名称(必须) loader: 'babel-loader', }
-
同时我们需要修改.babelrc⽂件
{ "presets": [ [ "@babel/preset-env", { "modules": false, "targets": { "browsers": [ "> 1%", "last 2 versions", "not ie <= 8" ] } } ], "@babel/preset-react" ] }
-
修改主⽂件,键⼊React代码
import React from 'react' import ReactDom from 'react-dom' class App extends React.Component { render(){ return ( <div style={{color:"#333"}}> Hello </div> ) } } ReactDom.render(<App/>,document.getElementById("root"))
加载图片
在⽹⻚中不可避免的会依赖图⽚资源,在Webpack中加载图片通常涉及到使用file-loader
或url-loader
。
-
安装依赖
npm install --save-dev file-loader url-loader
-
修改配置
{ test: /\.(png|jpe?g|gif)$/i, use: [ { loader: 'file-loader', }, ], },
-
使用图片
在你的JavaScript或CSS文件中,你可以通过以下方式引入图片:import img from './path/to/image.png'; // 在JavaScript中使用 document.getElementById('image').src = img; // 在CSS中使用 .image { background-image: url('./path/to/image.png'); }
Webpack优化
webpack的优化有非常非常多内容,虽然内容都非常的多,我们也只需了解即可,到企业真正用到了的时候再去查看webpack文档即可。下面我通过ai输出了一些关于webpack优化的常用手段,大家可以看一看💪⛽️。
Webpack优化可以从多个方面进行,以提高构建速度、减少最终bundle的大小、改善开发体验和运行性能。以下是一些常用的Webpack优化策略:
优化构建速度
使用webpack-dashboard
webpack-dashboard
提供了一个更友好的Webpack输出界面,同时也有助于提高构建速度。
缩小文件搜索范围
- 使用
resolve.extensions
减少解析文件时的后缀尝试。 - 使用
resolve.alias
为常用模块创建别名。 - 使用
module.noParse
避免解析那些没有模块化的库。
利用缓存
- 使用
cache-loader
或开启其他loader的缓存功能。 - 使用
HardSourceWebpackPlugin
为模块提供中间缓存。
多线程/多实例构建
- 使用
thread-loader
或parallel-webpack
。
开启监听模式时优化
- 使用
watchOptions
来减少文件监听的开销。
优化输出文件
分割代码
- 使用
SplitChunksPlugin
来分割代码块。 - 使用动态导入(如
import()
)实现懒加载。
压缩代码
- 使用
TerserPlugin
压缩JavaScript。 - 使用
css-minimizer-webpack-plugin
压缩CSS。
移除无用的代码
- 使用
Tree Shaking
去除未引用的代码。 - 使用
_PURGE_
变量和_PURGE_|webpackChunkName
注释来清除未使用的样式。
图片优化
- 使用
image-webpack-loader
压缩图片。
优化运行性能
使用Preload/Prefetch
- 使用魔法注释
/* webpackPrefetch: true */
或/* webpackPreload: true */
来优化资源加载顺序。
使用CDN和缓存
- 在
output.publicPath
中使用CDN地址。 - 设置合适的缓存策略。
优化开发体验
使用Source Maps
- 配置
devtool
选项生成source maps。
热替换(HMR)
- 使用
webpack-dev-server
的HMR功能。
开发和生产环境的区分
- 使用环境变量和不同的配置文件(如
webpack.common.js
,webpack.dev.js
,webpack.prod.js
)。
其他优化
使用webpack-bundle-analyzer
- 分析bundle内容,找出优化的机会。
使用speed-measure-webpack-plugin
- 测量Webpack构建过程中各个阶段的时间。
使用webpackbar
- 显示构建进度条。
示例配置
以下是一个简单的Webpack优化配置示例:
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// ...
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
new OptimizeCSSAssetsPlugin({}),
],
splitChunks: {
chunks: 'all',
},
},
plugins: [
new CleanWebpackPlugin(),
// 其他插件...
],
// ...
};
以上仅列举了一些常见的Webpack优化策略,实际项目中可能需要根据具体情况选择合适的优化方法。
(以上👆webpack优化内容由ai输出,仅供参考)