偏架构的东西,解决问题即可。
结尾有现成的package.json
核心工具:
webpack webpack-cli webpack-dev-server
CSS:
css-loader style-loader
less less-loader
CSS兼容性
browserslist
postcss postcss-loader
autoprefixer
postcss-preset-env
资源文件
file-loader url-loader
插件
clean-webpack-plugin
html-webpack-plugin
copy-webpack-plugin
JS兼容性
@babel/core babel-loader
@babel/plugin-transform-arrow-functions
@babel/plugin-transform-block-scoping
@babel/preset-env
@babel/polyfill
core-js
regenerator-runtime
let path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "build.js",
path: path.resolve(__dirname, "build")
}
}
执行脚本
"build": "webpack --config webpack.config.js"
JS中引入样式文件
import "./a.css";
css-loader:处理css的导入,转为文件名数组
style-loader:读取数组,写入,包裹上style标签。
顺序:从后往前。
let path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "build.js",
path: path.resolve(__dirname, "build")
}, module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
}
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
作用:看看符合条件的浏览器版本有哪些。
在package.json中配置
"browserslist": [
">1%",
"last 4 version",
"not dead"
]
命令行调用
browserslist
处理JS中的CSS。
CSS=>样式树=>一番修改=>CSS。
插件决定怎么修改。
autoprefixer:自动加浏览器前缀插件。
postcss-preset-env:一堆流行的插件。
let postcss = {
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
}
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader', postcss]
}, {
test: /\.less$/,
use: ['style-loader', 'css-loader', postcss, 'less-loader']
}
]
效果:
处理css中导入的css的兼容性。
把css-loader换成:
let css={
loader:"css-loader",
options: {
importLoaders:1
}
}
1代表向前提交一级(postcss)
否则会漏掉。
let file={
loader: "file-loader",
options: {
esModule: false
}
}
{
test: /\.jpg$/,
use: [file]
}
function addImg(src) {
let e = document.createElement("img");
e.src = src;
document.body.appendChild(e);
}
let img = require("./a.jpg");
addImg(img);
body{
background-image: url("./a.jpg");
}
let css = {
loader: "css-loader",
options: {
importLoaders: 1,
esModule: false
}
}
let file = {
loader: "file-loader",
options: {
esModule: false,
name: "img/[name][hash:6].[ext]"
}
}
图片会被转码,收集进js中。
小图片适用,可以减少请求次数。
let file = {
loader: "url-loader",
options: {
esModule: false
}
}
按文件大小选择方式:
let file = {
loader: "url-loader",
options: {
esModule: false,
name: "img/[name][hash:6].[ext]",
limit: 24 * 1024
}
}
24kb以下:编码。
以上:单独的文件。
asset/resource:单独的文件
asset/inline:编码。
let file = {
type: "asset",
generator: {
filename: "img/[name][hash:6].[ext]"
}, parser: {
dataUrlCondition: {
maxSize: 24 * 1024
}
}
}
{
test: /\.jpg$/,
...file
}
举例:https://www.bootcss.com/p/font-awesome/
有用的文件夹:css,font
function addTag(tagName, attrName, attrValue) {
let e = document.createElement(tagName);
e.setAttribute(attrName, attrValue);
document.body.appendChild(e);
}
/*let img = require("./a.jpg");*/
/*
addImg(img);*/
require("./Font-Awesome-3.2.1/css/font-awesome.min.css")
addTag("i", "class", " icon-cloud-download");
{
test: /\.(jpg|otf|eot|svg|ttf|woff)$/,
...file
}
let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
//...
}, plugins: [
new Clean()
]
}
let Html = require('html-webpack-plugin');
plugins: [
new Clean(), new Html()
]
设置HTML模版
new Html({
template: "./public/index.html"
})
let Copy = require('copy-webpack-plugin');
new Copy({
patterns: [
{
from: "public",
globOptions: {
ignore: ['**/index.html']
}
}
]
})
@babel/plugin-transform-arrow-functions:箭头函数
@babel/plugin-transform-block-scoping:块级作用域
@babel/preset-env:流行的插件集合
let babel = {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
{
test: /\.js$/,
use: [babel]
}
效果:
效果:提供Promise函数。
let babel = {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env", {
useBuiltIns: 'usage',
corejs: 3
}]]
}
}
{
test: /\.js$/,
exclude:/node_modules/,
use: [babel]
}
运行服务器:
"scripts": {
"build": "webpack --config webpack.config.js",
"serve": "webpack serve --config webpack.config.js"
}
配置模块热更新:
1,配置文件中
target: "web",
devServer: {
hot: true
}
2,入口JS
require("./a")
if (module.hot) {
module.hot.accept(["./a.js"])
}
这样,a.js才能热更新。
package.json
{
"name": "demo",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "webpack --config webpack.build.js",
"serve": "webpack serve --config webpack.build.js",
"dist": "webpack --config webpack.dist.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.17.5",
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.16.11",
"autoprefixer": "^10.4.2",
"babel": "^6.23.0",
"babel-cli": "^6.26.0",
"babel-loader": "^8.2.3",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.2.4",
"core-js": "^3.21.1",
"css-loader": "^6.6.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"postcss": "^8.4.7",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.4.1",
"regenerator-runtime": "^0.13.9",
"style-loader": "^3.3.1",
"url-loader": "^4.1.1",
"webpack": "5.69.1",
"webpack-cli": "4.9.2",
"webpack-dev-server": "^4.7.4"
},
"browserslist": [
">1%",
"last 4 version",
"not dead"
]
}
生产配置:
生产环境没有dev-server。
let path = require("path");
let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;
let Html = require('html-webpack-plugin');
let Copy = require('copy-webpack-plugin');
let css = {
loader: "css-loader",
options: {
importLoaders: 1,
esModule: false
}
}
let postcss = {
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"]
}
}
}
let babel = {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env", {
useBuiltIns: 'usage',
corejs: 3
}]]
}
}
let file = {
type: "asset",
generator: {
filename: "file/[name][hash:6].[ext]"
}, parser: {
dataUrlCondition: {
maxSize: 24 * 1024
}
}
}
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
filename: "dist.js",
path: path.resolve(__dirname, "dist")
}, module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', css, postcss]
}, {
test: /\.less$/,
use: ['style-loader', css, postcss, 'less-loader']
}, {
test: /\.(jpg)$/,
...file
}, {
test: /\.(otf|eot|svg|ttf|woff)$/,
...file
}, {
test: /\.js$/,
exclude: /node_modules/,
use: [babel]
}
]
}, plugins: [
new Clean(),
new Html({
template: "./public/index.html"
}), new Copy({
patterns: [
{
from: "public",
globOptions: {
ignore: ['**/index.html']
}
}
]
})
]
}
开发配置:
开发环境不需要考虑兼容性。
let path = require("path");
let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;
let Html = require('html-webpack-plugin');
let Copy = require('copy-webpack-plugin');
let css = {
loader: "css-loader",
options: {
importLoaders: 1,
esModule: false
}
}
let file = {
type: "asset",
generator: {
filename: "file/[name][hash:6].[ext]"
}, parser: {
dataUrlCondition: {
maxSize: 24 * 1024
}
}
}
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "build.js",
path: path.resolve(__dirname, "build")
}, module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', css]
}, {
test: /\.less$/,
use: ['style-loader', css, 'less-loader']
}, {
test: /\.(jpg)$/,
...file
}, {
test: /\.(otf|eot|svg|ttf|woff)$/,
...file
}
]
}, plugins: [
new Clean(),
new Html({
template: "./public/index.html"
}), new Copy({
patterns: [
{
from: "public",
globOptions: {
ignore: ['**/index.html']
}
}
]
})
],
target: "web",
devServer: {
hot: true
}
}