可以去gitee看一下我里面有资料和demo:gitee:https://gitee.com/mus-z/webpack_learn
概述
webpack是前端模块打包器,把资源文件打包生成对应的bundle
比如.less需要先转化成浏览器识别的css才能解析
又比如js中使用了import的语法浏览器是识别不了的
会有依赖树状结构
五个核心概念
entry:入口,指示打包的起点文件
output:输出,指示打包资源bundles输出路径和命名
loader:处理非js文件(webpack自身只理解js、json),相当于翻译官
plugins:功能插件,可以做到优化、压缩、定义环境变量等
mode:模式氛围development和production模式
看演示~
上面是没有配置webpack.config.js的时候的webpack命令 ,生产环境会压缩代码,打包后的文件是处理成浏览器能识别的情况
一个干净的webpack.config.js
如何打包样式:
如果使用其他的比如less文件要继续配置loader
如何打包html:
使用html-webpack-plugin
默认创建一个空html,自动引入built.js
如果要有结构
打包图片:
老师在less中引入了图片
打包的时候,图片会报错,所以要使用处理图片的loader
但是这种情况下处理不了html引用的img图片,所以要用到html-loader
但是视频中发现会和url-loader的es6模式冲突,要关闭url-loader的esModule
不过经过自己测试这个已经解决了,不需要考虑这个冲突问题,下面是我用到的版本
“url-loader”: “^4.1.0”,
“webpack”: “^4.44.0”,
“webpack-cli”: “^3.3.12”,
“html-loader”: “^1.1.0”,
打包其他资源:
视频中以字体文件为例(用的阿里的图标库)
module:{
//对某种格式的文件进行转换处理
rules:[
{
test:/\.css$/,//使用正则匹配
use:[
//顺序从下到上
'style-loader',//把css-js引入到style
'css-loader',//把css转换成js
]
},{
//排除css、js、html、json
exclude:/\.(css|js|html|json)$/,
loader:'file-loader'
}
]
},
这样子大概是可以用的(不过特殊的需要处理的比如less、图片之类的在静态模板中是没有引用,可能还是要加loader,另外资源使用相对路径好像是不可以的,如果是import就可以)
热加载devServer
修改代码需要重新打包,这时候就需要devserver了,保证我们一些小的修改不需要重新打包
可以自动编译、自动打开浏览器、自动刷新项目
临时的打包文件是保存在内存中,不会更新到我们的文件夹
启动命令是
webpack-dev-server
需要全局安装
开发环境搭建
// 开发环境配置
const path =require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports={
entry:'./src/index.js',
output:{
filename:'built.js',
path:path.resolve(__dirname,'build')
},
module:{
rules:[
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test:/\.(png|jpg|gif)$/,
loader:'url-loader',
options:{
limit:8*1024,
name:'[hash:10].[ext]'
}
},
{
test:/\.html$/,
loader:'html-loader',
},
{
exclude:/\.(js|css|less|html|json|png|jpg|gif)$/,
loader:'file-loader',
options:{
limit:8*1024,
name:'[hash:10].[ext]'
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html'
})
],
mode:'development',
devServer:{
open:true,
compress:true,
port:3001,
contentBase:path.resolve(__dirname,'build')
}
}
讲道理我用了css、less、png、以及其他文件 确实是没问题的
src路径的话我就不动了,视频里面老师带着整理了下,其实就是相对路径转化的问题
后面主要是一个output路径的配置,像这样子就比较神奇了
能够制定output下的子目录
// 开发环境配置
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "built.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
limit: 8 * 1024,
name: "[hash:10].[ext]",
outputPath: "imgs",
},
},
{
test: /\.html$/,
loader: "html-loader",
},
{
exclude: /\.(js|css|less|html|json|png|jpg|gif)$/,
loader: "file-loader",
options: {
limit: 8 * 1024,
name: "[hash:10].[ext]",
outputPath: "default",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
],
mode: "development",
devServer: {
open: true,
compress: true,
port: 3001,
contentBase: path.resolve(__dirname, "build"),
},
};
生产环境的痛点
生产中痛点:css从js中提取、代码压缩、兼容性问题
css
之前也说过css是被js引入才导入的,这样会导致js很大,想要拆出来
需要使用插件mini-css-extract-plugin
// 开发环境配置
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/js/index.js",
output: {
filename: "js/built.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.less$/,
use: [
// "style-loader",
MiniCssExtractPlugin.loader,//代替style-loader不使用标签插入
"css-loader",
"less-loader",
],
},
{
test: /\.css$/,
use: [
// "style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new MiniCssExtractPlugin(),
],
mode: "development",
devServer: {
open: true,
compress: true,
port: 3001,
contentBase: path.resolve(__dirname, "build"),
},
};
之前定义的css文件被整合到main.css了
还可以通过传参的方式制定output的目录和文件名
new MiniCssExtractPlugin({
filename:'css/built.css'
}),
然后考虑css的兼容处理,一个loader一个插件
css兼容性处理:postcss-loader postcss-preset-env
还要配置browserslist,设置环境
// 生产环境配置
// process.env.NODE_ENV='development';//设置node为开发环境
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");//单独提取css的插件
module.exports = {
entry: "./src/js/index.js",
output: {
filename: "js/built.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.less$/,
use: [
// "style-loader",
MiniCssExtractPlugin.loader,//代替style-loader不使用标签插入
"css-loader",
"less-loader",
],
},
{
test: /\.css$/,
use: [
// "style-loader",//代替style-loader不使用标签插入
MiniCssExtractPlugin.loader,
//css兼容性处理:postcss-loader postcss-preset-env
"css-loader",
// 'postcss-loader',//不能使用默认配置,帮postcss找到package.json中的browserslist(自己配置)
// 而且browserslist默认是开发环境,要设置node环境变量,process.env.NODE_ENV='development'
// "browserslist":{
// "development":[
// "last 1 chrome version",
// "last 1 firefox version",
// "last 1 safari version"
// ],
// "production":[
// ">0.01%",
// "not dead",
// "not op_mini all"
// ]
// }
{
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:()=>[
require("postcss-preset-env")()
]
}
}
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new MiniCssExtractPlugin({
filename:'css/built.css'
}),
],
mode: "development",
devServer: {
open: true,
compress: true,
port: 3001,
contentBase: path.resolve(__dirname, "build"),
},
};
package.json加上
"browserslist":{
"development":[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production":[
">0.01%",
"not dead",
"not op_mini all"
]
}
能够看见兼容效果啦
至于压缩css也需要使用一个插件optimize-css-assets-webpack-plugin
安装好直接调用就行了
// 生产环境配置
// process.env.NODE_ENV='development';//设置node为开发环境
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");//单独提取css的插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');//压缩css文件
module.exports = {
entry: "./src/js/index.js",
output: {
filename: "js/built.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.less$/,
use: [
// "style-loader",
MiniCssExtractPlugin.loader,//代替style-loader不使用标签插入
"css-loader",
"less-loader",
],
},
{
test: /\.css$/,
use: [
// "style-loader",//代替style-loader不使用标签插入
MiniCssExtractPlugin.loader,
//css兼容性处理:postcss-loader postcss-preset-env
"css-loader",
// 'postcss-loader',//不能使用默认配置,帮postcss找到package.json中的browserslist(自己配置)
{
loader:'postcss-loader',
options:{
ident:'postcss',
plugins:()=>[
require("postcss-preset-env")()
]
}
}
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new MiniCssExtractPlugin({
filename:'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
],
mode: "development",
devServer: {
open: true,
compress: true,
port: 3001,
contentBase: path.resolve(__dirname, "build"),
},
};
js
下面学一下eslint语法检查
语法检查:对js进行规范,检查语法错误,eslint-loader eslint
设置检查规则 package.json中的eslintConfig中设置(airbnb)eslint-config-airbnb(-base)
不带base的有react相关eslint
tyarn add eslint-loader eslint eslint-plugin-import eslint-config-airbnb-base
const path =require('path')
const HtmlWebpackPlugin =require('html-webpack-plugin')
module.exports={
mode:'development',
entry:'./src/js/index.js',
output:{
filename:'js/built.js',
path:path.resolve(__dirname,'build')
},
module:{
rules:[
{
//语法检查:对js进行规范,检查语法错误,eslint-loader eslint
//只检查源代码,不检查第三方
//设置检查规则 package.json中的eslintConfig中设置(airbnb)
// "eslintConfig":{
// "extends":"airbnb-base"
// }
//eslint-config-airbnb-base->eslint eslint-plugin-import
test:/\.js$/,
exclude:/node_modules/,
loader:'eslint-loader',
options:{
},
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html'
})
]
}
听说eslint很可怕 我看看这么几行会咋样
运行webpack,2333
options:{
fix:true,//自动修复
},