Webpack入门到精通 五(常用配置)
为更好的阅读体验请移步掘金
初始化项目
mkdir webpack-config-demo
yarn init -y
yarn add webpack webpack-cli
package.json中添加
"scripts": {
"build": "webpack"
+ src/index.js
const fn = ()=>{
var a = 100
var b = 100
setTimeout(()=>{
console.log(a + b)
fn()
运行
yarn build
,就会看见当前打包好的
dist.js
文件
webpack build 支持IE
+ browserslistrc文件
[production]
[modern]
last 1 chrome version
last 1 firefox version
[ssr]
node 12
用babel-loader打包js
yarn add -D babel-loader @babel/core @babel/preset-env
+ webpack.config.js
module.exports = {
mode: "production",
module: {
rules: [
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env'],
['@babel/preset-react',
runtime: 'classic' //使用经典版
}
用babel-laoder打包jsx
yarn add @babel/preset-react
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react' //新增
}
测试
src/index.js
import JsxDemo from'./jsx-demo.jsx'
console.log(JsxDemo)
+ src/jsx-demo.jsx
const JsxDemo = () => {
return (
<div>jsx-demo</div>
export default JsxDemo
yarn build
给webpack配置eslint
eslint-config-react-app 此包包含Create React App使用的可共享 ESLint 配置。 npm link
yarn add -D
eslint-config-react-app
@typescript-eslint/eslint-plugin@^4.0.0
@typescript-eslint/parser@^4.0.0
babel-eslint@^10.0.0
eslint@^7.5.0
eslint-plugin-flowtype@^5.2.0
eslint-plugin-import@^2.22.0
eslint-plugin-jsx-a11y@^6.3.1
eslint-plugin-react@^7.20.3
eslint-plugin-react-hooks@^4.0.8
+ .eslintrc.js
module.exports = {
//继承 eslint-config-react-app这个里面包含create react app的eslint配置
"extends": "react-app",
rules: {
// jsx使用 react
'react/jsx-uses-react': [2],
// 提示要在 JSX 文件里手动引入 React
'react/react-in-jsx-scope': [2],
'no-console': [0]
}
让
webpack
可以感知到
eslint
的配置,从而在编译的过程中提示报错信息
yarn add eslint-webpack-plugin -D
webpack/config.js
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin({
extensions: ['.js', '.jsx'] //不加就不会去检测.jsx文件了
})],
// ...
};
在没加
eslint-webpack-plugin
之前虽然我们发现在编辑器中
eslint
给我们报错了,但是在我们运行
yarn build
的时候他还是可以编译成功的。如下图
下面我们来看看加完之后的情况,这个时候,不仅
eslint
报错了
webpack
构建的时候也会在控制台报错,这样就很好地使用了
eslint
。
用babel-loader打包TypeScript
yarn add @babel/preset-typescript -D
webpack.config.js
test: /\.[tj]sx?$/,
presets: [['@babel/preset-typescript']]
添加一个
test.tsx
,并且在
index.js
中引入,以下结果编译成功。
让eslint支持TypeScript
让
eslint
支持
ts
,添加相关的配置。
yarn add eslint-config-airbnb-typescript @types/react -D
.eslintrc.js
//覆盖之前的配置(检测ts代码)
overrides: [{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: './tsconfig.json',
extends: ['airbnb-typescript'],
rules: {
'@typescript-eslint/object-curly-spacing': [0],
'import/prefer-default-export': [0],
'no-console': [0],
'import/extensions': [0]
}]
我们运行
yarn build
发现此时编译还是可以成功的。
webpack.config.js 添加'.ts' '.tsx'
plugins: [new ESLintPlugin({
extensions: ['.js', '.jsx', '.ts', '.tsx'] //不加就不会去检测.jsx文件了
修改之后的效果
用babel-loader打包tsx
生成
tsconfig.json
文件。
npx tsc --init
"jsx": "react", // Specify JS
"strict": false, // 关闭严格模式
"noImplicitAny": true, //没有隐式的any
}
同样我们编写
tsx-demo.tsx
文件在
index.js
中引入进行测试。
CRLF 是什么?
一、LF和CRLF是什么
- CRLF 是 carriage return line feed 的缩写,中文意思是回车换行。
- LF 是 line feed 的缩写,中文意思也是换行。
- 它们都是文本换行的方式。
二、LF和CRLF区别
-
CRLF
: "\r\n", windows系统环境下的换行方式 -
LF
: "\n", Linux系统环境下的换行方式
让js和ts支持@alias
js 支持
webpack.config.js
const path = require('path')
resolve: {
alias: {
'@': path.join(__dirname, './src/')
ts 支持
tsconfig.json 添加
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
引入代码测试
让webpack支持scss
yarn add sass-loader sass style-loader css-loader -D
module.exports = {
module: {
rules: [
test: /\.s[ac]ss$/i,
//执行顺序从右到左
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
};
- sass-loader npm 点进去里面有具体的配置。
-
Vue-loader
这个是
Vue-loader
的官方文档
scss自动import全局文件
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
loader: "sass-loader",
options: {
//需要添加的字符串
additionalData: `
@import '@/var.scss';
sassOptions: {
includePaths: [__dirname] //基于当前目录
scss分享变量给js
可以让项目中用到的
css
变量用同一份
js
和
scss
共同维护一份变量。
+ scss-export.scss
:export {
border-color: $body-color;
index.js
import vars from './scss-export.scss';
console.log(vars)
webpack支持less文件
yarn add less less-loader -D
@import './_var.less';
body{
color: @color;
webpack.config.js
test: /\.less$/i,
use: [
loader: "style-loader",
loader: "css-loader",
options: {
modules: {
compileType: 'icss',
loader: "less-loader",
options: {
additionalData: `
@import './_var.less';
},
less分享给js
_var.less
@color: pink;
:export{
color: @color;
index.js
import vars from './_var.less';
console.log(vars)
对比scss 和less
要选的话就选
scss
stylus文件
style.stylus
color = black;
//变量分享给js
:export{
color: color
yarn add stylus stylus-loader -D
webpack.config.js
test: /\.styl$/,
use: [
loader: "style-loader",
loader: "css-loader",
options: {
modules: {
compileType: 'icss',
loader: "stylus-loader",
options: {
stylusOptions: {
import: [path.resolve(__dirname, "src/_var.styl")]
}
webpack config 重构
webpack.config.js
const cssLoaders = (...loaders) => [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
...loaders
生产页面单独提取css文件
mini-css-extract-plugin webpack文档
yarn add mini-css-extract-plugin -D
webpack.config.js
const cssLoaders = (...loaders) => [
// Creates `style` nodes from JS strings
mode === 'production' ? MiniCssExtractPlugin.loader : "style-loader",
// Translates CSS into CommonJS
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
...loaders
plugins: [
new ESLintPlugin({
extensions: ['.js', '.jsx', '.ts', '.tsx'] //不加就不会去检测.jsx文件了
mode === 'production' && new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
].filter(Boolean)
自动生成HTML页面
yarn add html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
filename: '[name].[contenthash].js'
plugins: [
new HtmlWebpackPlugin()
}
webpack优化 单独打包runtime
optimization: {
runtimeChunk: 'single', //运行时文件单独打包
为什么要单独打包runtime
-
runtime
里面的文件是webpack
为了运行main.js
文件所要依赖的文件。 -
如果不单独打包,如果我们修改了
webpack
的配置之后mian.js
里面的内容就会发生变化,用户的缓存就会失效,如果单独打包的话当修改完webpack
的配置之后只,如果我们没有改变main.js
里面的内容的话,就不会重新打包main.js
的内容,这样就可以节省宽带,提高用户访问页面的速度。
webpack优化 用splitChunks将node依赖单独打包
在编译的时候要缓存
React
等类库文件。
webpack优化 固定modules
webpack.config.js
optimization: {
moduleIds: 'deterministic',
runtimeChunk: 'single', //运行时文件单独打包
splitChunks: {
cacheGroups: {
vendor: {
priority: 10,
minSize: 0, /* 如果不写 0,由于 React 文件尺寸太小,会直接跳过 */
test: /[\\/]node_modules[\\/]/, // 为了匹配 /node_modules/ 或 \node_modules\
name: 'vendors', // 文件名
chunks: 'all', // all 表示同步加载和异步加载,async 表示异步加载,initial 表示同步加载
// 这三行的整体意思就是把两种加载方式的来自 node_modules 目录的文件打包为 vendors.xxx.js
// 其中 vendors 是第三方的意思
之后再运行
yarn build
可以看见引入了三个
js
文件
webpack 多页面
webpack.config.js
entry: {
main: './src/index.js',
admin: './src/admin.js'
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
chunks: ['main']
new HtmlWebpackPlugin({
filename: 'admin.html',
chunks: ['admin']
]
webpack优化 common插件
如果共有的文件就打包成一个文件,如果两个入口都同时引用了一个文件,
optimization: {
runtimeChunk: 'single', //运行时文件单独打包
splitChunks: {
cacheGroups: {
common: {
priority: 5,
minSize: 0,
minChunks: 2, //同一个文件至少被多少个入口引用了
chunks: 'all',
name: 'common'
-
runtime
为了运行mian.js
所要提供的代码。 -
node_modules
venders 全局的 -
common
模块间的 admin.js 和 index.js -
self
自身的
看这个打包之后页面引入
js
的顺序
无限多页面的实现思路
webpack.config.js
let entry = {}
let outputHtml = []
var pages = fs.readdirSync(path.resolve(__dirname, pagesDir))
pages.forEach((item)=>{
let name = item.replace('.js', '')
entry[name] = `${pagesDir}${item}`