每一个文件在打包时,都要过一遍每一个loader,命中则被相应的loader处理
    oneOf只会匹配其中一个loader
    eslint-loader以及babel-loader同为处理js文件,将eslint-loader单独出来,js即可被两个loader处理

    1. const { resolve } = require('path');
    2. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    3. const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
    4. const HtmlWebpackPlugin = require('html-webpack-plugin');
    5. // 定义nodejs环境变量:决定使用browserslist的哪个环境
    6. process.env.NODE_ENV = 'production';
    7. // 复用loader
    8. const commonCssLoader = [
    9. MiniCssExtractPlugin.loader,
    10. 'css-loader',
    11. {
    12. // 还需要在package.json中定义browserslist
    13. loader: 'postcss-loader',
    14. options: {
    15. ident: 'postcss',
    16. plugins: () => [require('postcss-preset-env')()]
    17. }
    18. }
    19. ];
    20. module.exports = {
    21. entry: './src/js/index.js',
    22. output: {
    23. filename: 'js/built.js',
    24. path: resolve(__dirname, 'build')
    25. },
    26. module: {
    27. rules: [
    28. {
    29. // 在package.json中eslintConfig --> airbnb
    30. test: /\.js$/,
    31. exclude: /node_modules/,
    32. // 优先执行
    33. enforce: 'pre',
    34. loader: 'eslint-loader',
    35. options: {
    36. fix: true
    37. }
    38. },
    39. {
    40. // 以下loader只会匹配一个
    41. // 注意:不能有两个配置处理同一种类型文件
    42. // 提升构建速度,没有oneOf则每个文件都会过一遍所有loader,或命中,或不命中该loader
    43. // eslint-loader和babel-loader都是处理js文件的,将eslint单独出来
    44. oneOf: [
    45. {
    46. test: /\.css$/,
    47. use: [...commonCssLoader]
    48. },
    49. {
    50. test: /\.less$/,
    51. use: [...commonCssLoader, 'less-loader']
    52. },
    53. /*
    54. 正常来讲,一个文件只能被一个loader处理。
    55. 当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
    56. 先执行eslint 在执行babel
    57. */
    58. {
    59. test: /\.js$/,
    60. exclude: /node_modules/,
    61. loader: 'babel-loader',
    62. options: {
    63. presets: [
    64. [
    65. '@babel/preset-env',
    66. {
    67. useBuiltIns: 'usage',
    68. corejs: {version: 3},
    69. targets: {
    70. chrome: '60',
    71. firefox: '50'
    72. }
    73. }
    74. ]
    75. ]
    76. }
    77. },
    78. {
    79. test: /\.(jpg|png|gif)/,
    80. loader: 'url-loader',
    81. options: {
    82. limit: 8 * 1024,
    83. name: '[hash:10].[ext]',
    84. outputPath: 'imgs',
    85. esModule: false
    86. }
    87. },
    88. {
    89. test: /\.html$/,
    90. loader: 'html-loader'
    91. },
    92. {
    93. exclude: /\.(js|css|less|html|jpg|png|gif)/,
    94. loader: 'file-loader',
    95. options: {
    96. outputPath: 'media'
    97. }
    98. }
    99. ]
    100. }
    101. ]
    102. },
    103. plugins: [
    104. new MiniCssExtractPlugin({
    105. filename: 'css/built.css'
    106. }),
    107. new OptimizeCssAssetsWebpackPlugin(),
    108. new HtmlWebpackPlugin({
    109. template: './src/index.html',
    110. minify: {
    111. collapseWhitespace: true,
    112. removeComments: true
    113. }
    114. })
    115. ],
    116. mode: 'production'
    117. };