美文网首页
webpack 配置

webpack 配置

作者: A_走在冷风中 | 来源:发表于2021-09-06 14:39 被阅读0次

    配置demo

    const webpack = require('webpack')
    const path = require('path')
    const { cleanWebpackPlugin } = require('clean-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    const TerserWebpackPlugin = require('terser-webpack-plugin')
    const InlineChunkHtmlPlugin = require('inline-chunk-html-plugin')
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    const PurgeCSSPlugin = require('purgecss-webpack-plugin')
    // 删除 build.js 内的注释
    class Myplugin {
      apply(compiler) {
        console.log('Myplugin 启动')
        // 第一个参数是方法名称
        compiler.hook.emit.tap('Myplugin', (compilation) => {
          // compilation => 可以理解为此次打包的上下文
          // compilation.assets 资源文件对象
          for (const name in compilation.assets) {
            // console.log(name) //资源文件名称
            // console.log(compilation.assets[name].source());//获取资源文件内容
            if (name.endsWith('.js')) {
              //判断是否以 .js 为结尾
              const contents = compilation.assets[name].source()
              const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
              compilation.assets.name = {
                source: () => withoutComments,
                size: () => withoutComments.length,
              }
            }
          }
        })
      }
    }
    module.exports = {
      entry: './src/main.css', //知道webpack打包入口路径
      output: {
        filename: 'bundle.js', //输出文件名
        path: path.join(__dirname, 'output'), //输出文件目录(要求绝对路径)
        publicPath: 'dist/', //打包后根目录文件夹
      },
      devtool: 'source-map',
      // Webpack Dev Serve 配置选项
      devServer: {
        hot: true, //开启 HMR
        contentBase: ['./public'], //静态资源路径
        proxy: {
          //代理配置
          '/api': {
            //什么开头的地址配置到 xx地址
            // http://loaclhost:8080/api/users => https://api.github.com/api/users
            target: 'https://api.github.com',
            pathRewite: {
              // http://loaclhost:8080/api/users => https://api.github.com/users
              '^/api': '',
            },
            // 不能使用 localhost:8080 作为请求 github 的主机名
            changeOrigin: true,
          },
        },
      },
      module: {
        rules: [
          {
            test: /.js$/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env'],
              },
            },
          },
          {
            test: /.css$/, //正则表达式,用来匹配文件路径
            use: [
              'style-loader', //通过style-loader将css-loader转换为style注入
              'css-loader',
            ], //loader使用路径,从后向前执行
          },
          {
            test: /.png$/,
            use: 'file-loader',
          },
          {
            test: /.png$/,
            use: {
              loader: 'url-loader',
              options: {
                //配置项
                limit: 10 * 1024, //10kb以下文件转换为 dataurl,其他自动转换为file-loader形式
              },
            },
          },
          {
            test: /.html$/,
            use: {
              loader: 'html-loader',
              options: {
                attrs: ['img:src', 'a:href'], //针对a标签中静态资源打包处理
              },
            },
          },
          {
            test: /.md$/,
            use: {
              loader: [
                'html-loader',
                './markdown-loader', //相对路径
              ],
            },
          },
          {
            test: /\.jsx?$/,
            use: ['babel-loader'],
          },
          {
            test: /\.ts$/,
            use: ['ts-loader'],
          },
          {
            test: /\.vue$/,
            use: ['vue-loader'],
          },
        ],
      },
      optimization: {
        //代码压缩功能配置
        usedExports: true, //只导出外部使用了的成员
        // minimize:true,//压缩代码,删除未引用代码
        minimize: [
          new TerserWebpackPlugin(), //开启js压缩
          // new OptimizeCssAssetsWebpackPlugin(), //这样只有打包的时候有效,但是js压缩插件会失效,所以还需要写js压缩
          // 被弃用  可使用purgecss-webpack-plugin 插件
          new PurgeCSSPlugin(),
        ],
        concarenateModules: true, //合并模块代码
        // sideEffects: true, //没有用到的模块是否有副作用 是否可以清除
        usedExports: true, // 标记不被使用的函数
        // package.json中配置sideEffects 可添加不被删除的文件
        splitChunks: {
          chunks: 'initial', // async initial all
          minSize: 20000, //所拆分的文件最小值(默认)
          maxSize: 20000,
          minChunks: 1, //至少被引用次数
          cacheGroups: {
            //对拆包的过程进行分组
            //自定义键值对
            syVendors: {
              test: /[\\/]node_modules[\\/]/,
              filename: 'js/[id]_vendor.js',
              priority: -10, //优先级
            },
            default: {
              minChunks: 2,
              filename: 'js/syy_[id].js',
              priority: -20,
            },
          },
        },
      },
      plugins: [
        new cleanWebpackPlugin(),
        // 生成index.html
        new HtmlWebpackPlugin({
          //对html文件配置
          title: 'webpack Plugin Sample',
          meta: {
            viewport: 'width=device-width',
          },
          template: './src/index.html', //指定模板文件渲染index
        }),
        // 用于生成about.html
        new HtmlWebpackPlugin({
          filename: 'about.html',
        }),
        //将runtime中的css导入html中
        new PurgeCSSPlugin({
          paths: glob.sync(`${resolveApp('./src')}/**/*`, { nodir: true }),
          safelist: function () {
            return {
              standard: ['body', 'html', 'ef'],
            }
          },
        }),
        // 开发过程中一般不会使用,所以在 devServer 中配置
        new CopyWebpackPlugin([
          'public', //将public下所有文件输出到dist目录
        ]),
        new Myplugin(),
        new webpack.HotModuleReplacementPlugin(), //开启HMR需要的插件
        new webpack.DefinePlugin({
          API_BASE_URL: "'http://api.example/com'", //变量会挂载到 env.API_BASE_URL
        }),
        new MiniCssExtractPlugin(), //使用这个就不需要使用style-loader,会将css生成.css文件
        new OptimizeCssAssetsWebpackPlugin(), //压缩生成的.css文件,可以将他写到  optimization/minizer 数组下
        //资源压缩
        new CompressionPlugin({
          test: /\.(css|js)$/,
          minRatio: 0.8,
          threshold: 0,
          algorithm: 'gzip',
        }),
        //往当前html中注入内容,不用单发请求,根据实际情况来使用
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime.*\.js/]),
        new BundleAnalyzerPlugin(), //打包时间和内容分析
      ],
    }
    

    区分打包环境

    paths.js

    const path = require('path')
    
    const appDir = process.cwd()
    
    const resolveApp = (relativePath) => {
      return path.resolve(appDir, relativePath)
    }
    
    module.exports = resolveApp
    

    webpack.common.js

    const resolveApp = require('./paths')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const { merge } = require('webpack-merge')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    // 时间分析
    const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
    const smp = new SpeedMeasurePlugin()
    
    // 导入其它的配置
    const prodConfig = require('./webpack.prod')
    const devConfig = require('./webpack.dev')
    
    // 定义对象保存 base 配置信息
    const commonConfig = (isProduction) => {
      return {
        entry: './src/main.css', //知道webpack打包入口路径
        output: {
          filename: 'bundle.js', //输出文件名
          path: path.join(__dirname, 'output'), //输出文件目录(要求绝对路径)
          publicPath: 'dist/', //打包后根目录文件夹
        },
        resolve: {
          extensions: ['.js', '.json', '.ts', '.jsx', '.vue'],
          alias: {
            '@': resolveApp('./src'),
          },
        },
        optimization: {
          runtimeChunk: true,
        },
        devtool: 'source-map',
        // Webpack Dev Serve 配置选项
        module: {
          rules: [
            {
              test: /.js$/,
              use: {
                loader: 'babel-loader',
                options: {
                  presets: ['@babel/preset-env'],
                },
              },
            },
            {
              test: /\.css$/,
              use: [
                isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
                {
                  loader: 'css-loader',
                  options: {
                    importLoaders: 1,
                    esModule: false,
                  },
                },
                'postcss-loader',
              ],
              sideEffects: true,
            },
            {
              test: /.png$/,
              use: 'file-loader',
            },
            {
              test: /.png$/,
              use: {
                loader: 'url-loader',
                options: {
                  //配置项
                  limit: 10 * 1024, //10kb以下文件转换为 dataurl,其他自动转换为file-loader形式
                },
              },
            },
            {
              test: /.html$/,
              use: {
                loader: 'html-loader',
                options: {
                  attrs: ['img:src', 'a:href'], //针对a标签中静态资源打包处理
                },
              },
            },
            {
              test: /.md$/,
              use: {
                loader: [
                  'html-loader',
                  './markdown-loader', //相对路径
                ],
              },
            },
            {
              test: /\.jsx?$/,
              use: ['babel-loader'],
            },
            {
              test: /\.ts$/,
              use: ['ts-loader'],
            },
            {
              test: /\.vue$/,
              use: ['vue-loader'],
            },
          ],
        },
        plugins: [
          //输出文件内容
          new HtmlWebpackPlugin({
            //自定义title
            title: 'copyWebpackPlugin',
            template: './public/index.html',
          }),
        ],
      }
    }
    module.exports = (env) => {
      const isProduction = env.production
    
      process.env.NODE_ENV = isProduction ? 'production' : 'development'
    
      // 依据当前的打包模式来合并配置
      const config = isProduction ? prodConfig : devConfig
    
      const mergeConfig = merge(commonConfig(isProduction), config)
    
      return smp.wrap(mergeConfig)
    }
    
    

    webpack.dev.js

    const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    module.exports = {
      mode: 'development',
      devtool: 'cheap-module-source-map',
      target: 'web',
      devServer: {
        hot: true, //开启 HMR
        contentBase: ['./public'], //静态资源路径
        proxy: {
          //代理配置
          '/api': {
            //什么开头的地址配置到 xx地址
            // http://loaclhost:8080/api/users => https://api.github.com/api/users
            target: 'https://api.github.com',
            pathRewite: {
              // http://loaclhost:8080/api/users => https://api.github.com/users
              '^/api': '',
            },
            // 不能使用 localhost:8080 作为请求 github 的主机名
            changeOrigin: true,
          },
        },
      },
      plugins: [
        new ReactRefreshWebpackPlugin(),
        new VueLoaderPlugin(), //vue 热更新
      ],
    }
    
    

    webpack.prod.js

    const webpack = require('webpack')
    const resolveApp = require('./paths')
    const { cleanWebpackPlugin } = require('clean-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    const TerserWebpackPlugin = require('terser-webpack-plugin')
    const InlineChunkHtmlPlugin = require('inline-chunk-html-plugin')
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    const PurgeCSSPlugin = require('purgecss-webpack-plugin')
    // 删除 build.js 内的注释
    class Myplugin {
      apply(compiler) {
        console.log('Myplugin 启动')
        // 第一个参数是方法名称
        compiler.hook.emit.tap('Myplugin', (compilation) => {
          // compilation => 可以理解为此次打包的上下文
          // compilation.assets 资源文件对象
          for (const name in compilation.assets) {
            // console.log(name) //资源文件名称
            // console.log(compilation.assets[name].source());//获取资源文件内容
            if (name.endsWith('.js')) {
              //判断是否以 .js 为结尾
              const contents = compilation.assets[name].source()
              const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
              compilation.assets.name = {
                source: () => withoutComments,
                size: () => withoutComments.length,
              }
            }
          }
        })
      }
    }
    module.exports = {
      optimization: {
        //代码压缩功能配置
        usedExports: true, //只导出外部使用了的成员
        // minimize:true,//压缩代码,删除未引用代码
        minimize: [
          new TerserWebpackPlugin(), //开启js压缩
          // new OptimizeCssAssetsWebpackPlugin(), //这样只有打包的时候有效,但是js压缩插件会失效,所以还需要写js压缩
          // 被弃用  可使用purgecss-webpack-plugin 插件
          new PurgeCSSPlugin(),
        ],
        concarenateModules: true, //合并模块代码
        // sideEffects: true, //没有用到的模块是否有副作用 是否可以清除
        usedExports: true, // 标记不被使用的函数
        // package.json中配置sideEffects 可添加不被删除的文件
        splitChunks: {
          chunks: 'initial', // async initial all
          minSize: 20000, //所拆分的文件最小值(默认)
          maxSize: 20000,
          minChunks: 1, //至少被引用次数
          cacheGroups: {
            //对拆包的过程进行分组
            //自定义键值对
            syVendors: {
              test: /[\\/]node_modules[\\/]/,
              filename: 'js/[id]_vendor.js',
              priority: -10, //优先级
            },
            default: {
              minChunks: 2,
              filename: 'js/syy_[id].js',
              priority: -20,
            },
          },
        },
      },
      plugins: [
        new cleanWebpackPlugin(),
        // 生成index.html
        new HtmlWebpackPlugin({
          //对html文件配置
          title: 'webpack Plugin Sample',
          meta: {
            viewport: 'width=device-width',
          },
          template: './src/index.html', //指定模板文件渲染index
        }),
        // 用于生成about.html
        new HtmlWebpackPlugin({
          filename: 'about.html',
        }),
        //将runtime中的css导入html中
        new PurgeCSSPlugin({
          paths: glob.sync(`${resolveApp('./src')}/**/*`, { nodir: true }),
          safelist: function () {
            return {
              standard: ['body', 'html', 'ef'],
            }
          },
        }),
        // 开发过程中一般不会使用,所以在 devServer 中配置
        new CopyWebpackPlugin([
          'public', //将public下所有文件输出到dist目录
        ]),
        new Myplugin(),
        new webpack.HotModuleReplacementPlugin(), //开启HMR需要的插件
        new webpack.DefinePlugin({
          API_BASE_URL: "'http://api.example/com'", //变量会挂载到 env.API_BASE_URL
        }),
        new MiniCssExtractPlugin(), //使用这个就不需要使用style-loader,会将css生成.css文件
        new OptimizeCssAssetsWebpackPlugin(), //压缩生成的.css文件,可以将他写到  optimization/minizer 数组下
        //资源压缩
        new CompressionPlugin({
          test: /\.(css|js)$/,
          minRatio: 0.8,
          threshold: 0,
          algorithm: 'gzip',
        }),
        //往当前html中注入内容,不用单发请求,根据实际情况来使用
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime.*\.js/]),
        new BundleAnalyzerPlugin(), //打包时间和内容分析
      ],
    }
    

    相关文章

      网友评论

          本文标题:webpack 配置

          本文链接:https://www.haomeiwen.com/subject/mazuwltx.html