Webpack 中 webpack.config.js 文件的一些常见配置

Webpack 中 webpack.config.js 文件的一些常见配置和解释

cnpm install style-loader css-loader less less-loader url-loader file-loader html-loader postcss-loader postcss-preset-env eslint eslint-loader eslint-plugin-import eslint-config-airbnb-base babel-loader @babel/core @babel/preset-env @babel/polyfill core-js html-webpack-plugin workbox-webpack-plugin thread-loader add-asset-html-webpack-plugin -D

webpack.config.js 文件内容

/**
 * webpack 配置文件, 指定其执行的工作
 * entry
 * output
 * module
 * loader 引入 ==> 使用
 * plugins 引入 ==> 声明 ==> 使用
 * mode
 */
// [cnpm i style-loader css-loader less less-loader url-loader file-loader html-loader postcss-loader postcss-preset-env eslint eslint-loader eslint-plugin-import eslint-config-airbnb-base babel-loader @babel/core @babel/preset-env @babel/polyfill core-js html-webpack-plugin workbox-webpack-plugin thread-loader add-asset-html-webpack-plugin -D]
// resolve 用于拼接绝对路径的方法
const {resolve} = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 提取 css 为单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 压缩 css 文件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// PWA
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');

// 启动 browserslist 中开发环境 (设置 nodejs 环境变量)
process.env.NODE_ENV = "development";


// 复用 CSS loader
const commonCssLoader = [
    // 创建 style 标签, 将 js 中的样式资源插入进行, 添加到 head 中生效
    // 'style-loader',
    // MiniCssExtractPlugin.loader 替代 style-loader 用于单独提取 css 样式, 而不是创建 style 标签
    {
        loader: MiniCssExtractPlugin.loader,
        options: {}
    },
    // 将 css 文件变成 commonjs 模块加载 js 中, 里面内容是样式字符串
    {
        loader: 'css-loader'
    },
    // css 兼容性处理: postcss
    // 使用 postcss 默认配置
    // 'postcss-loader',
    // 修改 postcss 默认配置 postcss.config.js
    {
        loader: "postcss-loader"
    }
];


// 复用照片 options
const commonImgOptions = (prePath) => {
    return {
        // 图片大小小于 10kb 就会被 base64 处理 (优点: 减少请求数量)
        limit: 10 * 1024,
        // 关闭 url-loader 中 ES6 模块化, 使用 commonjs 解析
        esModule: false,
        // 给图片进行从命名 [hash:10]: 文件 hash 值的前十位, [ext]: 文件的原扩展名
        name: prePath + '/[hash:10].[ext]',
        // 打包输出路径
        // outputPath: prePath,
        // 统一设置公共路径
        publicPath: '../'
    }
}


// 插件提出来
const plugins = [
    // new HtmlWebpackPlugin(): 建立一个空 HTML 文件, 自动打包所有输出的资源 (JS/CSS)
    new HtmlWebpackPlugin({
        // 建立指定的 HTML 文件
        template: "./src/view/index.html",
        // 对输出的 HTML 文件选择路径和自定义文件名
        filename: 'webpack.html',
        // 压缩 HTMl 代码
        minify: {
            // 移除空格
            collapseWhitespace: true,
            // 移除注释
            removeComments: true
        }
    }),
    // 提取 css 为单独文件 [cnpm i mini-css-extract-plugin -D]
    new MiniCssExtractPlugin({
        // 对输出的 css 文件选择路径和自定义文件名
        filename: 'css/webpack.[contenthash:10].css'
    }),
    // 压缩 css
    new OptimizeCssAssetsWebpackPlugin(),
    // PWA: 渐进式网络开发应用程序(离线可访问) workbox --> workbox-webpack-plugin
    new WorkboxWebpackPlugin.GenerateSW({
        // 1.帮助 serviceworker 快速启动 2.删除旧的 serviceworker
        // 生成一个 serviceworker 配置文件~
        clientsClaim: true,
        skipWaiting: true
    }),
    // 告诉 webpack 哪些库不参与打包, 同时使用时的名称也得变~
    new webpack.DllReferencePlugin({
        manifest: resolve(__dirname, "dll/manifest.json")
    }),
    // 将某个文件打包输出去, 并在 html 中自动引入该资源
    new AddAssetHtmlWebpackPlugin({
        filepath: resolve(__dirname, "dll/jquery.js")
    })
];


module.exports = {
    // 入口起点文件
    entry: [
        './src/index.js',
        './src/view/index.html'
    ],
    // 输出内容
    output: {
        // 输出文件名
        // chunkhash: 根据 chunk 生成的 hash 值. 如果打包来源于同一个 chunk, 那么 hash 值就一样
        // contenthash: 根据文件的内容生成 hash 值. 不同文件 hash 值一定不一样
        filename: "js/webpack.[contenthash:10].js",
        // 输出路径, __dirname: 当前文件路径的绝对路径
        path: resolve(__dirname, 'build')
    },
    // loader 配置
    module: {
        // 不同的文件配置不同的资源
        rules: [
            {
                // eslint 语法检查
                test: /\.js$/,
                // 只检查自己写的代码
                exclude: /node_modules/,
                // 优先执行
                enforce: "pre",
                // 以后执行
                // enforce: "post",
                loader: 'eslint-loader',
                // 使用 airbnb 提供的 eslint 规则检查, 在 package.json 中设置 eslintConfig
                options: {
                    // 自动修复 eslint 错误
                    fix: true
                }
            },
            {
                // 以下 loader 指挥执行一个, 不能有两项配置处理同一类文件
                oneOf: [
                    {
                        // 匹配 css 文件
                        test: /\.css$/,
                        // 使用那些 loader 进行处理
                        use: [...commonCssLoader]
                    },
                    {
                        // 匹配 less 文件
                        test: /\.less$/,
                        // 使用那些 loader 进行处理
                        use: [
                            ...commonCssLoader,
                            // 将 less 文件编译成 css 文件
                            'less-loader'
                        ]
                    },
                    {
                        // 匹配照片文件
                        test: /\.(jpg|png|gif)$/,
                        // 使用那些 loader 进行处理
                        loader: 'url-loader',
                        // 打包条件
                        options: commonImgOptions('img')
                    },
                    {
                        // 匹配 icon 文件
                        test: /\.(icon|ttf|bin|eot|woff|woff2|svg)$/,
                        // 使用那些 loader 进行处理
                        loader: 'url-loader',
                        // 打包条件
                        options: commonImgOptions('icon')
                    },
                    {
                        // 匹配 HTML 中 img 标签文件
                        test: /\.html$/,
                        // 使用那些 loader 进行处理 (负责引入, 从而由 url-loader 处理)
                        loader: 'html-loader'
                    },
                    {
                        // 匹配其他资源
                        exclude: /\.(css|js|less|jpg|png|gif|icon|ttf|bin|eot|woff|woff2|svg|html|json)$/,
                        // 使用那些 loader 进行处理
                        loader: 'file-loader',
                        // 打包条件
                        options: {
                            // 进行从命名 [hash:10]: 文件 hash 值的前十位, [ext]: 文件的原扩展名
                            name: 'other/[hash:10].[ext]',
                            // 打包输出路径
                            // outputPath: 'other',
                            // 统一设置公共路径
                            publicPath: '../'
                        }
                    },
                    {
                        // 基础 JS 兼容性处理 babel-loader @babel/core @babel/preset-env
                        // 全面 JS 兼容性处理 @babel/polyfill
                        // 需要 JS 兼容性处理 core-js
                        test: /\.js$/,
                        // 排除第三方
                        exclude: /node_modules/,
                        use: [
                            /**
                             * 开启多进程打包 thread-loader
                             * 进程启动大概为 600ms, 进程通信也有开销, 只有工作消耗时间比较长, 才需要多进程打包
                             */
                            {
                                loader: 'thread-loader',
                                options: {
                                    // 进行为 2
                                    workers: 2
                                }
                            },
                            {
                                loader: 'babel-loader',
                                // 预设: 指示 babel 做怎么样的兼容性处理
                                options: {
                                    presets: [
                                        [
                                            "@babel/preset-env",
                                            {
                                                //按需加载
                                                useBuiltIns: 'usage',
                                                //指定 core-js 版本
                                                corejs: {
                                                    version: 3
                                                },
                                                // 指定兼容性做到哪个版本浏览器
                                                targets: {
                                                    chrome: '60',
                                                    firefox: '60',
                                                    ie: '9',
                                                    edge: '17',
                                                    safari: '10'
                                                }
                                            }
                                        ]
                                    ],
                                    // 开启 babel 缓存
                                    /**
                                     * 缓存:
                                     *  babel缓存
                                     *      cacheDirectory : true文件资源缓存
                                     *  hash:每次 webpack 构建时会生成一个唯一的 hash 值. 问题: 因为 js 和 css 同时使用一个 hash 值.
                                     *      如果重新打包, 会导致所有缓存失效. (可能我却只改动一个文件)
                                     *  chunkhash: 根据 chunk 生成的 hash 值. 如果打包来源于同一个 chunk, 那么 hash 值就一样
                                     *  contenthash: 根据文件的内容生成 hash 值. 不同文件 hash 值一定不一样
                                     */
                                    cacheDirectory: true
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    // plugins 配置
    plugins: plugins,
    /**
     * 代码分割
     * 1. 可以将 node_modules 中代码单独打包一个 chunk 最终输出
     * 2. 自动分析多入口 chunk 中, 有没有公共的文件. 如果有会打包成单独一个 chunk
     */
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    },
    // 模式 development: 开发模式, production: 生产模式. (生产模式下会自动压缩 JS 代码)
    mode: "production",
    // 忽略 npm 下载的包进行打包
    externals: {
        // 拒绝 JQuery 打包
        jquery: "JQuery"
    },

    // 开发服务器 devServer: 用来自动化. (自动编译, 自动打开浏览器, 自动刷新浏览器~~) 只会在内存中编译打包, 没有任何输出.
    // 启动指令: npx webpack-dev-server [cnpm i webpack-dev-server -D]
    devServer: {
        contentBase: resolve(__dirname, 'build'),
        // 启动 gzip 压缩
        compress: true,
        // 端口号
        port: 3000,
        // 自动打开浏览器
        open: true,
        // HMR: hot module replacement 热模块替换 / 模块热替换 只能处理非入口文件
        // 作用: 一个模块发生变化, 只会重新打包这一个模块 (而不是打包所有模块)
        hot: true
        // 不要显示启动服务器日志信息
        // clientLogLevel: 'none',
        // 除了一些基本启动信息以外, 其他内容都不要显示
        // quiet: true,
        // 如果出错了, 不要全屏提示~
        // overlay: false
    },
    // source-map: 一种提供源代码到构建后代码映射技术 (如果构建后代码出错了, 通过映射可以追踪源代码错误)
    /**
     * [inline-|hidden-|eval-][nosources-][cheap-[module-]]
     * source-map: 外联 [错误代码准确信息和源代码的错误位置]
     * inline-source-map: 内联-只生成一个内联 [错误代码准确信息和源代码的错误位置]
     * hidden-source-map: 外联 [错误代码错误原因, 但是没有错误位置, 不能追踪源代码错误, 只能提示到构建后代码的错误位置]
     * eval-source-map: 内联-每个文件都生成一个内联 [错误代码准确信息和源代码的错误位置]
     * nosources-source-map: 外联 [错误代码准确信息, 但是没有任何源代码信息]
     * cheap-source-map: 外联 [错误代码准确信息, 源代码的错误位置, 只能精确的行]
     * cheap-module-source-map: 外联 [module: 会将 loader 的 source map 加入]
     * 开发环境: 速度快, 调试更友好 ===> eval-source-map
     *  速度快 (eval > inline > cheap >...)
     *  调试更友好 source-map > cheap-module-source-map
     * 生产环境: 源代码要不要隐藏? 调试要不要更友好, 基本不用内联 ===> source-map
     */
    devtool: 'eval-source-map'
}


/**
 * tree shaking: 去除无用代码
 * 前提: 1.必须使用 ES6 模块化 2.开启 production 环境作用: 减少代码体积
 * 在 package.json 中配置
 *  "sideEffects": false 所有代码都没有副作用(都可以进行 tree shaking)
 *  问题:可能会把 css/@babel/polyfill (副作用) 文件干掉
 *  "sideEffects": ["*.css", "*.less"]
 */

package.json 内容

  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  },
  "sideEffects": [
    "*.css",
    "*.less"
  ]

webpack.dll.js 内容

/**
 * webpack --config webpack.dll.js
 * cnpm i jquery
 */

const {resolve} = require('path');
const webpack = require('webpack');


module.exports = {
    entry: {
        // 最终打包生成的 [name] --> jquery, ['jquery'] --> 要打包的库是 jquery
        jquery: ['jquery']
    },
    output: {
        filename: '[name].js',
        path: resolve(__dirname, 'dll'),
        // 打包的库里面向外暴露出去的内容叫什么名字
        library: '[name]_[hash]'
    },
    plugins: [
        // 打包生成一个 manifest.json --> 提供和 jquery 映射
        new webpack.DllPlugin({
            // 映射库的暴露的内容名称
            name: '[name]_[hash]',
            // 输出文件路径
            path: resolve(__dirname, 'dll/manifest.json')
        })
    ]
};

postcss.config.js 内容

module.exports = {
    plugins: [
        require('postcss-preset-env')
    ]
}

index.js 内容

// 引入 JS 兼容
// import '@babel/polyfill'

/**
 * 1.运行指令:
 *  开发环境: webpack ./src/index.js -o ./build --mode=development
 *    webpack 会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/main.js 整体打包环境,是开发环境
 *  生产环境: webpack ./src/index.js -o ./build --mode=production
 *    webpack 会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/main.js 整体打包环境,是生产环境
 * 2. webpack 可以处理 js/json 不能处理 css/img 等资源
 */
import { library } from '@fortawesome/fontawesome-svg-core';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
import { fab } from '@fortawesome/free-brands-svg-icons';
import 'font-awesome/css/font-awesome.css';
import './css/style.css';
import './css/style_less.less';
import data from './data/data.json';
import print from './js/print';

library.add(fas, far, fab);
console.log(data);

function add(x, y) {
  return x + y;
}

// eslint-disable-next-line
console.log(add(1, 2)); // 下一行 eslint 所有规则都失效 (下一行不进行 eslint 检查)

const a = function a() {
  console.log(12);
};

console.log(a);

print();

// js 热加载
if (module.hot) {
  // 监听到 HMR 就执行
  module.hot.accept('./js/print.js', () => {
    print();
  });
}
/**
 * 通过 js 代码, 让某个文件被单独打包成一个 chunk import 动态导入语法: 能将某个文件单独打包
 * 懒加载~: 当文件需要使用时才加载~
 * 预加载 prefetch: true 会在使用之前, 提前加载 js 文件 (等其他资源加载完毕, 浏览器空闲了, 再偷偷加载资源) 兼容性差, 慎用
 */
// import(/* webpackChunkName: 'test' */ "./js/test").then((result) => {
//     // "文件加载成功~"
//     // eslint-disable-next-line
//     console.log(result);
// }).catch(() => {
//     // eslint-disable-next-line
//     console.log('文件加载失败~');
// });

// 注册 serviceworker
// 处理兼容性问题

/**
 * 2. sw代码必须运行在服务器上
 *   -->nodejs
 *   -->
 *   cnpm i serve -g
 *   serve -s build 启动服务器, 将 build 目录下所有资源作为静态资源暴露出去
 */
/**
 * "eslintConfig": {
 *   "extends": "airbnb-base",
 *   "env": {
 *     "browser": true
 *   }
 * },
 */
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js').then(() => {
      // eslint-disable-next-line
      console.log('sw 注册成功了~');
    }).catch(() => {
      // eslint-disable-next-line
      console.log('sw 注册失败了~');
    });
  });
} else {
  // eslint-disable-next-line
  console.log('sw 不兼容~');
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值