如何支持 IE

1
2
3
4
5
6
7
8
9
10
11
.browserslistrc
[production] # 正式环境
> 1% # 支持全世界大于1%的浏览器
ie 9

[modern] # 开发环境
last 1 chrome version
last 1 firefox version

[ssr]
node 12

用 babel-loader 打包 JS

其实 webpack 就可以打包 JS 了,为什么还要用 babel-loader 呢?因为他的功能更强大,

1
npm install -D babel-loader @babel/core @babel/preset-env webpac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// webpack.config.js

module.exports = {
node: 'production',
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}

用 babel-loader 打包 JSX

babel-preset-react

1
npm install --save-dev @babel/preset-react
1
"presets": ["@babel/preset-react"]

给 webpack 配置 ESLint 插件

  • 让编辑器提示
    1
    yarn add -D babel-eslint eslint eslint-config-react-app eslint-plugin-flowtype eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // .eslintrc.js
    module.exports = {
    extends: ['react-app'],
    rules: {
    // 0 忽略 ,1 警告, 2 报错
    'react/jsx-uses-react': [2],
    // 提示要在 JSX 文件里手动引入 React
    'react/react-in-jsx-scope': [2]
    }
    }
  • 让 webpack 提示
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    yarn add - D eslint-webpack-plugin

    const ESLintPlugin = require('eslint-webpack-plugin')

    module.exports = {
    mode: 'production',
    plugins: [
    new ESLintPlugin({
    extensions: ['.js', '.jsx']
    })
    ],
    module: {
    rules: [
    {
    test: /\.jsx?$/,
    exclude: /(node_modules|bower_components)/,
    use: {
    loader: 'babel-loader',
    options: {
    presets: [
    ['@babel/preset-env'],
    ['@babel/preset-react', {runtime: 'classic'}],
    ],
    }
    }
    }
    ]
    }
    }

如何使用 babel-loader 打包 TypeScript

1
yarn add -D @babel/preset-typescript
1
"presets": ["@babel/preset-typescript"]

让 ESLint 支持 TS

为什么不用 TSLint?因为作者不维护了

1
yarn add -D @typescript-eslint/eslint-plugin eslint-config-airbnb-typescript typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
// ...
overrides: [{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: './tsconfig.json',
},
extends: ['airbnb-typescript'],
rules: {
'@typescript-eslint/object-curly-spacing': [0],
'import/prefer-default-export': [0],
},
}],
}

让 babel-loader 支持 TSX

1
yarn add -D @types/react
1
2
// tsconfig.json
"jsx": "react"

支持 alias

  • 让 JS 支持 @
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const path = require('path')
    const ESLintPlugin = require('eslint-webpack-plugin')

    module.exports = {
    // ...
    resolve: {
    alias: {
    '@': path.resolve(__dirname, './src/')
    },
    },
    }
  • 让 TS 支持 @
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
    "baseUrl": ".",
    "paths": {
    "@/*": ["src/*"]
    },
    }
    }

支持 SCSS

1
yarn add -D css-loader sass sass-loader style-loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
}
]
}
}

让 scss 自动 import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
additionalData: `@import "~@/scss-vars.scss";`,
sassOptions: {
includePaths: [__dirname]
}
},
],
}
]
}
}

scss 分享变量给 JS

1
2
3
4
// 最好新建一个文件
:export {
color: $color;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
},
},
},
{
loader: 'sass-loader',
options: {
additionalData: `@import "~@/scss-vars.scss";`,
sassOptions: {
includePaths: [__dirname]
}
},
],
}
]
}
}

支持 Less

1
yarn add -D less less-loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
}
},
},
'less-loader',
]
},
]
}
}

让 less 自动 import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
}
},
},
{
loader: 'less-loader',
options: {
additionalData: `@import "~@/less-vars.less";`,
lessOptions: {
includePaths: [__dirname]
}
},
},
]
},
]
}
}

分享 Less 变量给 JS

和 scss 同理

支持 stylus

1
yarn add -D stylus stylus-loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  // ...
module: {
rules: [
// ...
{
test: /\.styl(us)?$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
}
},
},
'stylus-loader',
]
},
]
}
}

让 stylus 自动 import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
test: /\.styl(us)?$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
}
},
},
{
loader: 'stylus-loader',
options: {
stylusOptions: {
import: [path.resolve(__dirname, 'src/stylus-vars.styl')]
}
},
}
]
},

分享 stylus 变量给 JS

同理

提取 CSS,并且文件加 hash

1
npm install --save-dev mini-css-extract-plugin
1
2
3
4
5
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
}),
],
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const createLoader = (...loaders) => [
mode === 'production' ?
MiniCssExtractPlugin.loader:
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
compileType: 'icss',
}
},
},
...loaders
]

自动生成 HTML

1
yarn add -D html-webpack-plugin
1
2
3
plugins: [
new HtmlWebpackPlugin()
],

给 JS 文件加 hash

1
2
3
4
5
module.exports = {
output: {
filename: '[name].[contenthash].js'
},
}