前端一定要知道的 webpack 配置基础知识

1. entry(入口起点)

【用法】entry: string | [string]

1.1 单一入口

entry 属性单入口语法:

module.exports = {
    entry: {
        main: './src/main.js'
    }
    //...
};

简写语法:

module.exports = {
    entry: './src/main.js'
    //...
};

也可以将一个文件路径数组传递给entry属性

module.exports = {
    entry: ['./src/main_1.js', './src/main_2.js']
    //...
};

【优点】当通过一个入口为应用程序快速配置webpack时,单一入口的语法是很好的选择。

【缺点】使用这种语法方式它的扩展性、配置灵活性不大。

1.2 对象语法

【用法】entry: { string | [string] } | {}

entry 属性对象语法:

module.exports = {
    entry: {
        app: './src/app.js',
        adminApp: './src/adminApp.js'
    }
    //...
};

对象语法会比较繁琐。然而,这是应用程序中定义入口的最可扩展的方式。

描述入口的对象,属性:

dependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。

filename: 指定要输出的文件名称。

import: 启动时需加载的模块。

library: 指定 library 选项,为当前 entry 构建一个 library。

runtime: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。

publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址。

“webpack 配置的可扩展”  是指,这些配置可以重复使用,并且可以与其他配置组合使用。这是一种流行的技术,用于将关注点从环境(environment)、构建目标(build target)、运行时(runtime)中分离。然后使用专门的工具(如 webpack-merge)将它们合并起来。

1.3 常见场景

1.3.1 分离 app(应用程序) 和 vendor(第三方库) 入口

module.exports = {
    entry: {
        main: './src/app.js',
        vendor: './src/vendor.js'
    }
    //...
};

以上代码告诉 webpack 我们想要配置 2 个单独的入口点。

这样你就可以在 vendor.js 中存入未做修改的必要 library 或文件(例如 Bootstrap, jQuery, 图片等),然后将它们打包在一起成为单独的 chunk。内容哈希保持不变,这使浏览器可以独立地缓存它们,从而减少了加载时间。

1.3.1 多页面应用程序

module.exports = {
    entry: {
        pageOne: './src/pageOne/index.js',
        pageTwo: './src/pageTwo/index.js',
        pageThree: './src/pageThree/index.js'
    }
    //...
};

以上告诉 webpack 需要三个独立分离的依赖图。

在多页面应用程序中,server 会拉取一个新的 HTML 文档给你的客户端。页面重新加载此新文档,并且资源被重新下载。然而,这给了我们特殊的机会去做很多事,例如使用 optimization.splitChunks 为页面间共享的应用程序代码创建 bundle。由于入口起点数量的增多,多页应用能够复用多个入口起点之间的大量代码/模块,从而可以极大地从这些技术中受益。

2. output(输出)

可以通过配置 output 选项,告知 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个 entry 起点,但只能指定一个 output 配置。

2.1 用法

在 webpack 配置中,output 属性的最低要求是,将它的值设置为一个对象,然后为将输出文件的文件名配置为一个 output.filename:

module.exports = {
    //...
    output: {
        filename: 'bundle.js'
    }
};

此配置将一个单独的 bundle.js 文件输出到 dist 目录中。对于单一入口起点,filename 会是一个静态名称。

2.1.1 使用入口名称

module.exports = {
    //...
    output: {
        filename: '[name].bundle.js'
    }
};

2.1.2 使用内部 chunk id

module.exports = {
    //...
    output: {
        filename: '[id].bundle.js'
    }
};

2.1.3 使用由生成的内容产生的 hash

module.exports = {
    //...
    output: {
        filename: '[contenthash].bundle.js'
    }
};

2.1.4 结合多个替换组合使用

module.exports = {
    //...
    output: {
        filename: '[name].[contenthash].bundle.js'
    }
};

2.1.5 使用函数返回 filename

module.exports = {
    //...
    output: {
        filename: (pathData) => {
            return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
        }
    }
};

2.2 多个入口起点

如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用 [占位符substitutions 来确保每个文件具有唯一的名称。

module.exports = {
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name].js',
        path: __dirname + '/dist'	//path:output 目录对应一个绝对路径。
    }
};

写入到dist目录:./dist/app.js, ./dist/search.js

2.3 高级进阶

对资源使用 CDN 和 hash 的复杂示例:

module.exports = {
    //...
    output: {
        path: '/home/proj/cdn/assets/[fullhash]',
        publicPath: 'https://cdn.example.com/assets/[fullhash]/'
    }
};

如果在编译时,不知道最终输出文件的 publicPath 是什么地址,则可以将其留空,并且在运行时通过入口起点文件中的 webpack_public_path 动态设置。

__webpack_public_path__ = myRuntimePublicPath;

3. loader(加载器)

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 "load(加载)" 模块时预处理文件

module.exports = {
    module: {
        rules: [
            { test: /\.css$/, use: 'css-loader' },
            { test: /\.ts$/, use: 'ts-loader' }
        ]
    }
};

module.rules允许你在 webpack 配置中指定多个 loader。

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    // [style-loader](/loaders/style-loader)
                    { loader: 'style-loader' },
                    // [css-loader](/loaders/css-loader)
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true
                        }
                    },
                    // [sass-loader](/loaders/sass-loader)
                    { loader: 'sass-loader' }
                ]
            }
        ]
    }
};

loader 执行顺序,从右到左(或从下到上)地取值(evaluate)/执行(execute)。在下面的示例中,从 sass-loader 开始执行,然后继续执行 css-loader,最后以 style-loader 为结束。

4. plugins(插件)

由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    plugins: [
        /* uglifyJsPlugin 用来对js文件进行压缩,从而减小js文件的大小 */
        new UglifyJSPlugin({
            //启用文件缓存,类型:Boolean|String 默认值:false 。
            //boolean:启用/禁用;String:启用文件缓存并设置缓存目录路径。
            cacheDir: '.cache/',
            parallel: 10,//多进程并行运行以提高构建速度.类型:Boolean|Number 默认值:false
            mangle: {
                screw_ie8: false //默认是true, 会把支持IE8的代码clear掉
            },
            mangleProperties: {
                screw_ie8: false
            },
            compress: {
                warnings: false,//删除一些无用代码的时候,不提示警告
                drop_debugger: true,
                drop_console: true,//过滤日志
                screw_ie8: false
            },
            output: {
                screw_ie8: false
            }
        })
    ]
}

通过配置 screw-ie8 :false 来支持IE8

5. mode(模块)

告知 webpack 使用相应模式的内置优化

module.exports = {
    mode: 'production'
};
};
复制代码

production模式下会启用UglifyJsPlugin插件(移除未使用的内容和文件压缩),分别用production和development打包,编译的区别:

1.development打包后,一些没有依赖的方法 变量 文件会保留,production则会移除。

2.production打包后,代码会进行压缩,比development的文件小。

选项****描述****
development会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
production会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.

6. resolve(解析)

module.exports = {
    resolve: {
        extensions: ['', '.js', '.jsx', '.less', '.css', '.svg'],
        alias: {
            src: path.join(__dirname, '../src'),
            components: path.join(__dirname, '../src/components'),
            routes: path.join(__dirname, '../src/bizRoutes'),
            views: path.join(__dirname, '../src/views'),
            assets: path.join(__dirname, '../src/assets')
        }
    }
};

Extensions:自动解析确定的扩展,能够使用户在引入模块时不带扩展

Alias:创建 import 或 require 的别名,来确保模块引入变得更简单。

例如,一些位于 src/ 文件夹下的常用模块:

就像这样:

import pic_sfz_zm from '../src/assets/images/ytj/pic_sfz_zm.png';

你可以这样使用别名:

import pic_sfz_zm from 'assets/images/ytj/pic_sfz_zm.png';

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值