npm install webpack webpack-cli --save-dev
./src/index.js
,但你可以通过在 webpack configuration
中配置 entry
属性,来指定一个(或多个)不同的入口起点import './index.css'
body{
background-color:green;
}
const path = require('path');
module.exports = {
entry: './src/index.js',
};
output
属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件./dist/main.js
,其他生成文件默认放置在 ./dist
文件夹中。webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'main.js'
+ }
};
JavaScript
和 JSON
文件webpack
能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
devtool:false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
+ module: {
+ rules: [
+ { test: /\.css$/, use: ['style-loader','css-loader']}
+ ]
+ }
};
src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack5</title>
</head>
<body>
</body>
</html>
const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool:false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [
{ test: /\.css$/, use: ['style-loader','css-loader']}
]
},
+ plugins: [
+ new HtmlWebpackPlugin({template: './src/index.html'})
+ ]
};
--mode
用来设置模块内的process.env.NODE_ENV
cross-env
用来设置node环境的process.env.NODE_ENV
DefinePlugin
用来设置模块内的全局变量production
webpack serve
的mode默认为development
process.env.NODE_ENV
获取当前的环境变量,无法在webpack配置文件中获取此变量 "scripts": {
"build": "webpack",
"dev": "webpack serve"
},
index.js
console.log(process.env.NODE_ENV);// development | production
webpack.config.js
console.log('NODE_ENV',process.env.NODE_ENV);// undefined
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack --mode=development serve"
},
module.exports = {
mode: 'development'
}
process.env.NODE_ENV
获取当前的环境变量node环境
(webpack 配置文件中)下获取当前的环境变量plugins:[
new webpack.DefinePlugin({
'process.env.NODE_ENV':JSON.stringify(process.env.NODE_ENV)
})
]
index.js
console.log(NODE_ENV);// production
webpack.config.js
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// undefined
console.log('NODE_ENV',NODE_ENV);// error !!!
node环境
下的变量NODE_ENVpackage.json
"scripts": {
"build": "cross-env NODE_ENV=development webpack"
}
webpack.config.js
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development
npm install webpack-dev-server --save-dev
类别 | 配置名称 | 描述 |
---|---|---|
output | path | 指定输出到硬盘上的目录 |
output | publicPath | 表示的是打包生成的index.html文件里面引用资源的前缀 |
devServer | publicPath | 表示的是打包生成的静态文件所在的位置(若是devServer里面的publicPath没有设置,则会认为是output里面设置的publicPath的值) |
devServer | static | 用于配置提供额外静态文件内容的目录 |
module.exports = {
devServer: {
static: path.resolve(__dirname, 'public'),
port: 8080,
open: true
}
}
"scripts": {
"build": "webpack",
+ "dev": "webpack serve"
}
npm i style-loader css-loader -D
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool:false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.css$/, use: ['style-loader','css-loader'] }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
src\bg.css
body{
background-color: green;
}
src\index.css
@import "./bg.css";
body{
color:red;
}
src\index.js
+import './index.css';
npm i less less-loader -D
npm i node-sass sass-loader -D
npm rebuild node-sass
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool: false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
+ { test: /\.less$/, use: ['style-loader','css-loader', 'less-loader'] },
+ { test: /\.scss$/, use: ['style-loader','css-loader', 'sass-loader'] }
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
};
src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack5</title>
</head>
<body>
+ <div id="less-container">less-container</div>
+ <div id="sass-container">sass-container</div>
</body>
</html>
src\index.js
import './index.css';
+import './less.less';
+import './sass.scss';
src\less.less
@color:blue;
#less-container{
color:@color;
}
src\sass.scss
$color:orange;
#sass-container{
color:$color;
}
::placeholder
可以选择一个表单元素的占位文本,它允许开发者和设计师自定义占位文本的样式。autoprefixer
和browsers
选项npm i postcss-loader postcss-preset-env -D
postcss.config.js
let postcssPresetEnv = require('postcss-preset-env');
module.exports={
plugins:[postcssPresetEnv({
browsers: 'last 5 version'
})]
}
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devtool: false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
+ { test: /\.css$/, use: ['style-loader', 'css-loader','postcss-loader'] },
+ { test: /\.less$/, use: ['style-loader','css-loader','postcss-loader','less-loader'] },
+ { test: /\.scss$/, use: ['style-loader','css-loader','postcss-loader','sass-loader'] }
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
};
src\index.css
@import "./bg.css";
body{
color:red;
}
+#root {
+ background-color: red;
+ width: 100px;
+ height: 10px;
+ transform: rotate(10deg);
+}
src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack5</title>
</head>
<body>
<div id="less-container">less-container</div>
<div id="sass-container">sass-container</div>
+ <div id="root"></div>
</body>
</html>
{
+ "browserslist": {
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ],
+ "production": [
+ ">0.2%"
+ ]
+ }
}
raw-loader
=> asset/source
导出资源的源代码file-loader
=> asset/resource
发送一个单独的文件并导出 URLurl-loader
=> asset/inline
导出一个资源的 data URIurl-loader
,并且配置资源体积限制实现module.exports = {
module:{
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
"@babel/preset-react"
]
},
}
],
exclude:/node_modules/
},
+ {
+ test: /\.png$/,
+ type: 'asset/resource'
+ },
+ {
+ test: /\.ico$/,
+ type: 'asset/inline'
+ },
+ {
+ test: /\.txt$/,
+ type: 'asset/source'
+ },
+ {
+ test: /\.jpg$/,
+ type: 'asset',
+ parser: {
+ dataUrlCondition: {
+ maxSize: 4 * 1024 // 4kb
+ }
+ }
+ }
]
},
experiments: {
asset: true
},
};
src\index.js
+ import png from './assets/logo.png';
+ import ico from './assets/logo.ico';
+ import jpg from './assets/logo.jpg';
+ import txt from './assets/logo.txt';
+ console.log(png,ico,jpg,txt);
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties @babel/plugin-proposal-private-property-in-object @babel/plugin-proposal-private-methods -D
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development',
devtool: false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
},
module: {
rules: [
+ {
+ test: /\.jsx?$/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ["@babel/preset-env", '@babel/preset-react'],
+ plugins: [
+ ["@babel/plugin-proposal-decorators", { legacy: true }],
+ ["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
+ ["@babel/plugin-proposal-private-methods", { "loose": true }],
+ ["@babel/plugin-proposal-class-properties", { loose: true }],
+ ],
+ },
+ },
+ },
{ test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader','postcss-loader', 'less-loader'] },
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'postcss-loader','sass-loader'] },
{
test: /\.(jpg|png|gif|bmp|svg)$/,
type:'asset/resource',
generator:{
filename:'images/[hash][ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
};
src\index.js
+function readonly(target,key,descriptor) {
+ descriptor.writable=false;
+}
+
+class Person{
+ @readonly PI=3.14;
+}
+let p1=new Person();
+p1.PI=3.15;
+console.log(p1)
jsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true
}
}
npm install eslint eslint-loader babel-eslint --D
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'development',
devtool: false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
module: {
rules: [
+ {
+ test: /\.jsx?$/,
+ loader: 'eslint-loader',
+ enforce: 'pre',
+ options: { fix: true },
+ exclude: /node_modules/,
+ },
{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
"presets": ["@babel/preset-env"],
"plugins": [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
["@babel/plugin-proposal-private-methods", { "loose": true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
]
}
},
include: path.join(__dirname, 'src'),
exclude: /node_modules/
},
{ test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader','postcss-loader', 'less-loader'] },
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'postcss-loader','sass-loader'] },
{
test: /\.(jpg|png|bmp|gif|svg)$/, use: [{
loader: 'url-loader', options: {
limit: 10
}
}]
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' })
]
};
src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack5</title>
</head>
<body>
+ <div id="root"></div>
</body>
</html>
src\index.js
+import React from "react";
+import ReactDOM from "react-dom";
+ReactDOM.render("hello",document.getElementById("root"));
+
+function readonly(target,key,descriptor) {
+ descriptor.writable=false;
+}
+
+class Person{
+ @readonly PI=3.14;
+}
+let p1=new Person();
+p1.PI=3.15;
.eslintrc.js
module.exports = {
root: true,
parser:"babel-eslint",
//指定解析器选项
parserOptions: {
sourceType: "module",
ecmaVersion: 2015
},
//指定脚本的运行环境
env: {
browser: true,
},
// 启用的规则及其各自的错误级别
rules: {
"indent": "off",//缩进风格
"quotes": "off",//引号类型
"no-console": "error",//禁止使用console
}
}
npm i eslint-config-airbnb eslint-loader eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks and eslint-plugin-jsx-a11y -D
eslintrc.js
module.exports = {
"parser":"babel-eslint",
"extends":"airbnb",
"rules":{
"semi":"error",
"no-console":"off",
"linebreak-style":"off",
"eol-last":"off"
//"indent":["error",2]
},
"env":{
"browser":true,
"node":true
}
}
.vscode\settings.json
{
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
如果你有单独的后端开发服务器 API,并且希望在同域名下发送 API 请求 ,那么代理某些 URL 会很有用。
devServer: {
proxy: {
"/api": 'http://localhost:3000'
}
}
devServer: {
proxy: {
"/api": {
target: 'http://localhost:3000',
pathRewrite:{"^/api":""}
}
}
}
devServer: {
onBeforeSetupMiddleware(devServer){// express()
devServer.app.get('/api/users', (req, res) => {
res.json([{ id: 1 }, { id: 2 }]);
});
}
}
webpack-dev-middleware就是在 Express 中提供 webpack-dev-server
静态服务能力的一个中间件
npm install webpack-dev-middleware --save-dev
const express = require('express');
const app = express();
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackOptions = require('./webpack.config');
webpackOptions.mode = 'development';
const compiler = webpack(webpackOptions);
app.use(webpackDevMiddleware(compiler, {}));
app.listen(3000);
webpack-dev-middleware
的好处是可以在既有的 Express 代码基础上快速添加 webpack-dev-server 的功能,同时利用 Express 来根据需要添加更多的功能,如 mock 服务、代理 API 请求等