此文项目代码:https://github.com/bei-yang/I-want-to-be-an-architect
码字不易,辛苦点个star,感谢!
引言
此篇文章主要涉及以下内容:
-
webpack
定义 -
webpack
核心概念 - 常用
loader
- 常用
plugins
什么是webpack
webpack is a module bundler.(模块打包工具)
Webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
- 官方网站:https://webpack.js.org/
- 中文网站:https://www.webpackjs.com/
测试:启动webpack打包
// es moudule 模块引入
// commonJs 模块引入
import add from "./a"; //需要使用es moudule导出
import minux from "./b";////需要使用es moudule导出
npx webpack index.js //打包命令 使用webpack处理index.js这个文件
总结:webpack 是一个模块打包工具,可以识别出引入模块的语法 ,早起的webpack只是个js模块的打包工具,现在可以是css,png,vue的模块打包工具
安装
-
环境:nodeJs https://nodejs.org/en/
版本参考官网发布的最新版本,可以提升webpack的打包速度
全局 不推荐
npm install webpack webpack-cli -g//webpack-cli 可以帮助我们在命令行里使用npx ,webpack等相关指令
webpack -v
npm uninstall webpack webpack-cli -g
- 局部安装 项目内安装
npm install webpack webpack-cli --save-dev //-D
webpack -v //command not found 默认在全局环境中查找
npx webpack -v// npx帮助我们在项目中的node_modules里查找webpack
- 安装指定版本
npm info webpack//查看webpack的历史发布信息
npm install [email protected] webpack-cli -D
webpack 配置文件
零配置是很弱的,特定的需求,总是需要自己进行配置
当我们使用npx webpack index.js时,表示的是使用webpack处理打包,名为index.js的入口模块。默认放在当前目录下的dist目录,打包后的模块名称是main.js,当然我们也可以修改
webpack有默认的配置文件,叫webpack.config.js,我们可以对这个文件进行修改,进行个性化配置
- 默认的配置文件:webpack.config.js
npx webpack //执行命令后,webpack会找到默认的配置文件,并使用执行
- 不使用默认的配置文件: webpackconfig.js
npx webpack --config webpackconfig.js //指定webpack使用webpackconfig.js文件来作为配置文件并执行
- 修改package.json scripts字段:有过vue react开发经验的同学 习惯使用npm run来启动,我们也可以修改下
"scripts":{
"bundle":"webpack"//这个地方不要添加npx ,因为npm run执行的命令,会优先使用项目工程里的包,效果和npx非常类似
}
npm run bundle
项目结构优化
dist
//打包后的资源目录
node_modules
//第三方模块
src
//源代码
css
images
index.js
package.json
webpack.config.js
Webpack 的核心概念
entry:
指定打包入口文件:Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入
entry:{
main: './src/index.js'
}
=====
entry:"./src/index.js"
entry:
output:
打包后的文件位置:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
output: {
publicPath:"xxx",
filename: "bundle.js",
// 必须是绝对路径
path: path.resolve(__dirname, "dist")
},
loader
模块转换器,用于把模块原内容按照需求转换成新内容。
webpack是模块打包工具,而模块不仅仅是js,还可以是css,图片或者其他格式
但是webpack默认只知道如何处理js模块,那么其他格式的模块处理,和处理方式就需要loader了
moudle
模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
module:{
rules:[
{
test:/\.xxx$/,
use:{
loader: 'xxx-load'
}
}
]
}
当webpack处理到不认识的模块时,需要在webpack中的module处进行配置,当检测到是什么格式的模块,使用什么loader来处理。
-
loader: file-loader:处理静态资源模块
loader: file-loader
原理是把打包入口中识别出的资源模块,移动到输出目录,并且返回一个地址名称
所以我们什么时候用file-loader呢?
场景:就是当我们需要模块,仅仅是从源代码挪移到打包目录,就可以使用file-loader来处理,txt,svg,csv,excel,图片资源啦等等
npm install file-loader -D
案例:
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/,
//use使用一个loader可以用对象,字符串,两个loader需要用数组
use: {
loader: "file-loader",
// options额外的配置,比如资源名称
options: {
// placeholder 占位符 [name]老资源模块的名称
// [ext]老资源模块的后缀
// https://webpack.js.org/loaders/file-loader#placeholders
name: "[name]_[hash].[ext]",
//打包后的存放位置
outputPath: "images/"
}
}
}
]
},
-
url-loader
可以处理file-loader所有的事情,但是遇到jpg格式的模块,会把该图片转换成base64格式字符串,并打包到js里。对小体积的图片比较合适,大图片不合适。
npm install url-loader -D
案例;
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
//小于2048,才转换成base64
limit: 2048
}
}
}
]
},
样式处理:
Css-loader 分析css模块之间的关系,并合成一个css
Style-loader 会把css-loader生成的内容,以style挂载到页面的heade部分
npm install style-loader css-loader -D
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
sass样式处理
sass-load 把sass语法转换成css ,依赖node-sass模块
npm install sass-loader node-sass -D
案例:
loader有顺序,从右到左,从下到上
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"] //loader是有执行顺序,从后往前
}
样式自动添加前缀:
Postcss-loader
npm i -D postcss-loader
webpack.config.js
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"]
},
新建postcss.config.js
安装autoprefixer
//npm i autoprefixer -D
module.exports = {
plugins: [require("autoprefixer")]
};
Plugins
plugin 可以在webpack运行到某个阶段的时候,帮你做一些事情,类似于生命周期的概念
扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
HtmlWebpackPlugin
htmlwebpackplugin会在打包结束后,自动生成一个html文件,并把打包生成的js模块引入到该html中。
npm install --save-dev html-webpack-plugin
配置:
title: 用来生成页面的 title 元素
filename: 输出的 HTML 文件名,默认是index.html, 也可以直接配置带有子目录。
template: 模板文件路径,支持加载器,比如 html!./index.html
inject: true | 'head' | 'body' | false ,注入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中。
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有用。
cache: true | false,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML 页面中
chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块)
案例:
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
...
plugins: [
new htmlWebpackPlugin({
title: "My App",
filename: "app.html",
template: "./src/index.html"
})
]
};
//index.html
<%= htmlWebpackPlugin.options.title %>
clean-webpack-plugin
在打包之前,先帮我们把生成目录删除一下
npm install --save-dev clean-webpack-plugin
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
...
plugins: [
new CleanWebpackPlugin()
]
mini-css-extract-plugin
将css文件抽离出来
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"]
}
new MiniCssExtractPlugin({
filename: "[name].css"
})
sourceMap
源代码与打包后的代码的映射关系
在dev模式中,默认开启,关闭的话 可以在配置文件里
devtool:"none"
devtool的介绍:https://webpack.js.org/configuration/devtool#devtool
eval:速度最快,使用eval包裹模块代码,
source-map: 产生.map
文件
cheap:较快,不用管列的信息,也不包含loader的sourcemap
Module:第三方模块,包含loader的sourcemap(比如jsx to js ,babel的sourcemap)
inline: 将.map
作为DataURI嵌入,不单独生成.map
文件
配置推荐:
devtool:"cheap-module-eval-source-map",// 开发环境配置
devtool:"cheap-module-source-map", // 线上生成配置
WebpackDevServer
提升开发效率的利器
每次改完代码都需要重新打包一次,打开浏览器,刷新一次,很麻烦
我们可以安装使用webpackdevserver来改善这块的体验
启动服务后,会发现dist目录没有了,这是因为devServer把打包后的模块不会放在dist目录下,而是放到内存中,从而提升速度
npm install webpack-dev-server -D
修改下package.json
"scripts": {
"server": "webpack-dev-server"
},
在webpack.config.js配置:
devServer: {
contentBase: "./dist",
open: true,
port: 8081
},
跨域:
联调期间,前后端分离,直接获取数据会跨域,上线后我们使用nginx转发,开发期间,webpack就可以搞定这件事
启动一个服务器,mock一个接口:
// npm i express -D
// 创建一个server.js 修改scripts "server":"node server.js"
//server.js
const express = require('express')
const app = express()
app.get('/api/info', (req,res)=>{
res.json({
name:'开课吧',
age:5,
msg:'欢迎来到开课吧学习前端高级课程'
})
})
app.listen('9092')
//node server.js
http://localhost:9092/api/info
项目中安装axios工具
//npm i axios -D
//index.js
import axios from 'axios'
axios.get('http://localhost:9092/api/info').then(res=>{
console.log(res)
})
会有跨域问题
修改webpack.config.js 设置服务器代理
proxy: {
"/api": {
target: "http://localhost:9092"
}
}
修改index.js
axios.get("/api/info").then(res => {
console.log(res);
});
你的赞是我前进的动力
求赞,求评论,求分享...