前端-webpack-学习笔记
1. 初识Webpack
生鸡蛋+米 ======== 源代码============ src
蛋炒饭=========== 构建(打包)之后的代码 ==========bulid/dist
构建:将程序员写的【源代码】,加工生成浏览器可以:高效、稳定运行的,兼容性好的代码
曾经是 grunt=>gulp=>现在是webpack
vue和react都用webpack
1.1 什么是webpack
- webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)
- 在webpack 看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理
- 它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)
为什么要用webpack打包
webpack是前端模块打包器,把资源文件打包生成对应的bundle
比如.less
需要先转化成浏览器识别的css
才能解析
又比如js
中使用了import
的语法浏览器是识别不了的
webpack基于node.js
1.2 webpack的五个核心概念:
-
【Entry:入口(Entry)】
指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。 -
【Ouput:输出(Output)】
指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名 -
【Loader:Loader 翻译官】
让 webpack 能 够去处理那些非 JavaScript文件(webpack 自 身 只 理 解JavaScript)。 -
【Plugins:插件(Plugins)】
可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。Plugins使用方式:先下载再引入再使用 -
【Mode:模式(Mode)】
指示 webpack使用相应模式的配置,有生成模式production和开发模式development
对loader理解
webpack本身只能处理js、json模块,如果要加载其他类型的文件(模块),就需要使用对应的loader
它本是是一个函数,接受源文件作为参数,返回转换的结果
loader一般以xxx-loader的方式命名,xxx代表了这个loader要做的转换功能,比如css-loader
对plugins理解
插件可以完成一些loader不能完成的功能
配置文件
webpack.config.js:用于存储webpack配置信息
1.3 webpack打包的基本流程
- 连接:webpack从入口js开始,递归的查找所有相关的模块,并【连接】起来形成一个图的结构
- 编译:将js模块中的模块化语法【编译】为浏览器可以直接运行的模块语法(当然其他类型的资源也会处理)
- 合并:将图中所有编译过的模块【合并】成一个或少量的几个文件,浏览器真正运行的是打包后的文件
1.4 live-reload(自动刷新)与HMR(热模替换)
相同点:
代码修改后都会自动重新编译打包
不同点:
live-reload:刷新整体页面,从而查看到最新代码的效果,页面状态全部是最新的
HMR:没有刷新整个页面,只是加载了修改模块的打包文件并运行,从而更新页面的局部界面,整个界面的其他部分的状态都还在
1.5 常用loader(面试)
1.6 常用pulgins(面试)
2. 初始化配置:
2.1 初始化+下载安装
npm init或者 yarn init #初始化,生成一个package.json
npm i webpack@4 webpack-cli@3 -g #全局安装webpack和webpack-cli (建议全局安装)
npm i webpack@4 webpack-cli@3 -D #安装全局依赖之后再在本地开发环境中安装这两个依赖包
2.2 运行指令
-
使用开发环境可以运行指令:
webpack ./src/js/app.js -o ./build/js/app.js --mode=development
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js。整体打包环境是开发环境
-
使用生产环境以运行指令:
webpack ./src/js/app.js -o ./build/js/app.js--mode=production
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js。整体打包环境是生产环境
结论:
webpack
能处理js/json
资源,不能处理css/img
等其他资源 生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化- 生产环境比开发环境多一个压缩js代码
- 不能将 js 的 es6 基本语法转化为 es5 以下语法(向下兼容)。
app.js是webpack的入口,所有外部文件(js、json、css、less等)都需要在这里引入使用
import {sub,sum} form './module1' # 注意不是解构赋值
import {data as d,message} form './module2'
import school form './module3'
import data form '../json/test.json'
2.3 配置打包入口与出口
建立一个webpack.config.js
- 该文件是webpack的配置文件,所有webpack的任务、用到的loader、plugins都要配置在这里
- 该文件要符合CJS模块化规范
# 引入Node中一个内置的path模块,专门用于解决路径问题
var path = require('path');
# 使用CJS模块化规范,暴露一个对象,该对象就是webpack的详细配置对象(规则)
module.exports = {
mode: 'development',//工作模式
entry: './src/js/app.js',//入口
output: { //出口(输出)
path: path.resolve(__dirname, 'bulid'), //输出文件的路径
filename: '/js/app.js'//输出文件的名字
}
};
直接使用命令就可以打包 webpack
就可以打包生成/bulid/
2.4 打包处理css文件
开发依赖:帮助程序员加工代码的库
生成依赖:帮助程序员实现功能效果的库
例如npm i jquey -D
开发依赖,上线就干掉,这样是不对的
在app.js
中 import '../css/demo.css'
步骤
- 安装对应的包 :
npm i css-loader less -D
,npm install style-loader -D
- 参考官网,写配置文件
module.exports = {
mode: 'development',//工作模式
entry: './src/js/app.js',//入口
output: { //出口(输出)
path: path.resolve(__dirname, 'bulid'), //输出文件的路径
filename: '/js/app.js'//输出文件的名字
},
# module.rules中配置一个一个的loader,一个对象是一个loader
module: {
rules: [
{
test: /\.css$/,# 该是要处理的文件
use: [
'style-loader',//创建style标签,将样式资源插入,添加到head中生效
'css-loader'//将css作为commmonjs模块加载js中,里面内容是样式字符串
]
}
]
}
};
2.5 打包处理less文件
在app.js
中 import '../css/demo.less'
- 安装less-loader和less:运行
npm i less-loader less -D
命令 - 在
webpack.config.js
的 module ->rules
数组中,添加 loader 规则如下:
module: {
rules: [
{ test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
}
css less简写形式
const baseCssLoader = ['style-loader','css-loader']
module.exports = {
mode: 'development',//工作模式
entry: './src/js/app.js',//入口
output: { //出口(输出)
path: path.resolve(__dirname, 'bulid'), //输出文件的路径
filename: '/js/app.js'//输出文件的名字
},
module: {
rules: [
{
test: /\.css$/,# 该是要处理的文件
use: [...baseCssLoader]
} ,
{
test: /\.scss$/,
use: [...baseCssLoader,'less-loader'] //编译less
}
]
}
2.6 打包HTML 资源
- 下载安装
npm i html-webpack-plugin -D
- 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
- 实例化
module: {},
plugins: [
//实例化HtmlWebpackPlugin
//功能:默认会创建一个空的html, 自动引入打包输出的所有资源(js/css)
new HtmlWebpackPlugin({
template: './src/index.html'//模板地址
})
]
};
2.7 打包样式中的图片file-loader
- 安装:
npm install file-loader -D
- 用法
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
//options: {outputPath:'/imgs'} //配置图片加工后的位置
//publicPath:'/bulid/imgs'//配置图片引入时前缀
options: {outputPath:'imgs'} #推荐
name:'[hash:5].[ext]' //配置生成图片的名字 5位哈希值+后缀
}
]
}
]
}
}
2.8 打包CSS图片资源 url-loader
- 安装:
npm install url-loader -D
- 比file-loader高级
- 用法
{
test: /\.(.jpg|png|gif)$/,
loader: 'url-loader',
options: {
options: {outputPath:'imgs'} #推荐
name:'[hash:5].[ext]' //配置生成图片的名字 5位哈希值+后缀
# 1 图片大小小于8kb,就会被base64处理
# 1.1 优点:减少请求数量(减轻服务器压力)
# 1.2 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024
}
}
2.8 打包HTML中的图片资源 html-loader
- 安装:
npm i html-loader -D
- 用法:
在这里插入代码片
{
test: /\.html$/,
// 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
loader: 'html-loader'
}
2.9 打包其他资源file-loader
把字体放到font文件中,与css同级
# 打包其他资源(除了html/js/css|jpg|png|gif|json资源以外的资源)
{
# 排除html/js/css|jpg|png|gif|json资源
exclude: /\.(css|js|html|jpg|png|gif|json)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath:'media'
}
}
3 devServer
【开发环境】
- 全局和局部都要安装
npm i webpack-dev-server -D
和npm i webpack-dev-server -g
- 用法
module.exports = {
mode: 'development',
entry: {
},
output: {
},
module{
},
plugins:[
],
devServer{
post:5000,//开启服务器的端口号
open:true, //自动打开浏览器
hot: true, //开启模块热(热模替换)只更新改变的地方
}
};
- 执行命令
webpack-dev-server
,自动打开浏览器,不在硬盘中生成bulid文件,(在5000占用的那个内存空间)
4 提取CSS为单独文件
全局安装 npm
初始化包 npm
正常局部安装用yarn
在package.json
中配置,之后可以直接用npm start
启动
- 新建文件夹
config
- 分别建立生产环境和开发环境配置文件
- 配置生产环境和开发环境配置文件
- 运行
npm run bulid
或者yarn bulid
提取CSS为单独文件
- 安装:
npm i mini-css-extract-plugin -D
# 1. 引入
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module: {
rules: [
{
test: /\.css$/,
use: [
// 不需要'style-loader',
# 2. 这个loader 取代style-loader。作用:提取js 中的css 成单独文件
MiniCssExtractPlugin.loader,
// 将css 文件整合到js 文件中
"css-loader",
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new MiniCssExtractPlugin({
# 3. 对输出的css 文件进行重命名
filename: "css/built.css",
}),
],
5. CSS兼容性处理
- 安装两个包:
npm install postcss-loader postcss-preset -D
- 修改配置文件
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [ "postcss-preset-env"],
},
},
},
],
},
],
},
- 修改
package.json
,加入browserslist
"browserslist": {
// 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
"development": [
"last 1 chrome version", //考虑最后一个版本的Chrome
"last 1 firefox version",
"last 1 safari version"
],
// 生产环境:默认是看生产环境
"production": [
">0.2%", //兼容市面上99.8%的浏览器
"not dead",//“死去”的浏览器不做兼容,例如IE8
"ie 10" //兼容IE10
"not op_mini all" //不做opera浏览器mini版的兼容
]
}
- 运行
yarn bulid
6. js语法检查
对js基本语法错误/隐患,提前进行检查
- 安装 loader:
npm install eslint-loader eslint
- 安装检查规则:
npm install eslint-config-airbnb-base eslint-plugin-import
- 配置文件 webpack.config.
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre', # 优先执行
loader: "eslint-loader",
options: {
fix: true,# 自动修复eslint的错误
},
},
],
},
4 配置package.json
"eslintConfig": {
"extends": "airbnb-base" #直接使用airbnb-base提供的规则
"env":{
"browser":true
}
}
- 执行
yarn bulid
7. JS语法转换 babel-loader @babel/core
将浏览器不能识别的新语法转换原来能识别的旧语法,做浏览器兼容性处理(ES6=》ES5)
- 安装loader
npm install babel-loader @babel/core @babel/preset-env
- 配置文件
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
// 预设:指示babel做怎么样的兼容性处理
presets: [ "@babel/preset-env",],
},
}
8. JS兼容性处理
- 基本js兼容性处理 --> @babel/preset-env
问题:只能转换基本语法,如promise高级语法不能转换- 全部js兼容性处理 --> @babel/polyfill 要在js文件中引入
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~- 需要做兼容性处理的就做:按需加载 --> core-js【使用3就不要使用2,也就是不要在js文件中引入@babel/polyfill】
- 安装loader :
npm install @babel/polyfill
- 使用
app.js
中:import '@babel/polyfill'
9. JS和HTML压缩
生产环境会自动压缩js代码,只需要将模式改成生产模式即可。在webpack.prod.js
中mode: 'production'
备注:若设置为production
,必须在new HtmlWebpackPlugin
时添加配置minify:false
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
# 压缩html代码
minify:false
})
]
10. 压缩CSS
- 安装 :
npm install optimize-css-asserts-webpack-plugin
- 引入 :在
webpack.prod.js
中var OptimizeCssAssetsPlugin = require('optimize-css-asserts-webpack-plugin')
- 配置插件
plugins: [
new OptimizeCssAssetsPlugin({
cssProcessPluginOptions: {
#移除所有注释
preset:['default',{discardComments:{ removeAll:true}}]
}
})
]