Webpack配置

Webpack配置

1. mode:模式

  1. development:开发模式

    启用 NamedChunksPluginNamedModulesPlugin

    NamedChunksPlugin:把chunk id变为一个字符串标识符。

    NamedModulesPlugin:当开启 HMR 的时候使用该插件会显示模块的相对路径,建议用于开发环境。

  2. production:生产模式

    启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginUglifyJsPlugin

    FlagDependencyUsagePlugin:

    FlagIncludedChunksPlugin:

    ModuleConcatenationPlugin

    NoEmitOnErrorsPlugin

    OccurrenceOrderPlugin

    SideEffectsFlagPlugin

    UglifyJsPlugin

  3. none:不开启任何插件

2. entry:入口

entry配置的多种形式:字符串、数组、对象、函数。

2.1 字符串

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

2.2 数组

作用:将多个资源预先合并,在打包时将数组中最后一个元素作为实际入口路径。

module.exports = {
        entry: ['babel-polyfill', './src/index.js']
}

2.3 对象

多入口文件配置

module.exports = {
        entry: {
                page1: './src/page1.js',
                page2: './src/page2.js'
        }
}

2.4 函数

module.exports = {
        entry: () => './src/index.js'
}

module.exports = {
        entry: () => ({
                // 添加一些动态逻辑获取工程的入口
                if (boolean) {
                        return './src/index.js'
                } else {
                        return './src/main.jss'
                }
                // 或者
                // 返回一个Promise对象进行异步操作
                return new Promise(resolve => resolve('./src/index.js'));
        })
}

注意:

  1. Webpack默认,bundle.js文件大于250KB(压缩前)会认为文件过大,会发生警告。
  2. 通过多入口将vendor(包含库,框架等第三方不常用模块打包产生的bundle)打包,提升效率
  3. 配置多页应用,减少资源体积。

3. output:资源出口

module.exports = {
        mode: 'development',
        entry: './src/index.js',
        output: {
                filename: 'bundle.js',
                path: path.join(__dirname, 'assets'),
                publicPath: '/dist/'
        }
}

output的配置项:

3.1 filename

控制输出资源的文件名

bundle.js: 设置为固定的文件名
[name].js: entry设置为对象的key值(上述2.3的page1.js和page2.js)
[hash].js: 当前打包的所有资源的hash
[chunkhash].js: 当前chunk内容的hash
[id]: 当前chunk的ID
[query]: filename配置项中的query

注意:

  1. 开发环境不必要设置chunkhash,强烈推荐生产环境配置chunkhash,目的是控制客户端缓存。

3.2 path

指定资源输出的位置,必须为绝对路径(默认为dist目录)。

{
        path: path.join(__dirname, 'dist')  // build构建后资源存储的位置
}

注意:

  1. Webpack-dev-server 也有publicPath参数,请设置该参数和webpack的path路径相同。

3.3 publicPath:

由JS或CSS内部请求的间接资源(异步加载的CSS,CSS请求图片、字体等)的请求位置。

当前html请求路径为:https://weixin.dongyin.net/coach/index.html
打包之后异步资源为chunk-a3b82d.js文件

1. 相对路径:以构建之后的html为基准,获取页面资源的相对路径(请求地址如果为https://www.test.com)
{
        publicPath: ''  // 请求地址为:https://weixin.dongyin.net/coach/chunk-a3b82d.js
        publicPath: './js'  // 请求地址:https://www.test.com/coach/js/chunk-a3b82d.js
    publicPath: '../assets' // 请求地址:https://www.test.com/assets/chunk-a3b82d.js
}

2. Host相关
{
        publicPath: '/' // 请求地址为:https://weixin.dongyin.net/chunk-a3b82d.js
        publicPath: '/js'   // 请求地址:https://www.test.com/coach/js/chunk-a3b82d.js
    publicPath: '/dist' // 请求地址:https://www.test.com/coach/dist/chunk-a3b82d.js
}

3. CDN相关
{
        publicPath: 'https://cdn.com'   // 请求地址为:https://cdn.com/chunk-a3b82d.js
        publicPath: '//cdn.com/app' // 请求地址为://cdn.com/app/chunk-a3b82d.js
}

4. Module

两个配置:

4.1 noParse

对指定的内容不解析:noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/

4.2 rules

一个web工程通常包含HTML、JS、CSS、模版、图片、字体、SVG等多种类型的静态资源,资源之间又存在着某种联系。

对于Webpack来说,这些静态资源都是模块,我们可以加载一个JS文件一样去加载他们,但是JS又确实不认识他们,于是有了Loader辅助webpack,认识各种各样的资源文件。

原理:

  1. 每个loader本身就是一个函数
  2. webpack4之前,函数输入和输出都是字符串
  3. webpack4之后,函数输入和输出支持抽象语法树(AST),目的减少重复代码解析
  4. webpack先对代码解析=>由每一个loader对解析结果进行一一处理=>处理完成,交给webpack继续处理

4.3 常用loader

{
        // 正则表达式,匹配成功的模块使用该规则
        test: /\.css$/,
        // string|array: 使用的loader
        use: 'raw-loader',
        // 排除指定目录下的模块
        exclude: /node_modules/,
        // 包含指定目录下的模块
        include: /src/,
        // 只有src/pages下的js文件加载css
        issuer: {
                test: '/\.js$/',
                include: /src/pages
        },
        // 强制该loader在所有loader之前执行,避免被其他loader更改过(比如:eslint-loader需要先执行)
        enforce: 'pre'
}

1. exclude和include同时存在且不冲突,取并集
2. exclude和include同时存在有冲突,exclude优先级高

1. raw-loader

raw-loader 解析文本文件(比如.txt后缀但不局限于.txt的文件)

{
        test: /\.txt$/,
        use: 'raw-loader'
}

2. 样式loader集合

sass-loader 解析sass/scss样式(sass-loader起连接作用,主要是node-sass解析sass/scss内容)

css-loader 解析css后缀的文件,解析结果返回字符串。

vue-style-loadere 基于 style-loader,被 vue-loader 依赖

style-loadercss-loader 的解析结果(字符串)以内联标签<style>形式插入到 <head> 标签内。

postcss 编译插件的容器,将接收的样式源代码交由编译插件处理,最后输出css。

{
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
}
{
        test: /\.scss$/,
        use: [
                /* config.module.rule('sass').oneOf('normal') */
        {
            loader: 'vue-style-loader',
            options: {
                sourceMap: false,
                shadowMode: false
            }
        },
        /* config.module.rule('scss').oneOf('normal').use('css-loader') */
        {
            loader: 'css-loader',
            options: {
                sourceMap: false,
                importLoaders: 2
            }
        },
        /* config.module.rule('scss').oneOf('normal').use('postcss-loader') */
        {
        loader: 'postcss-loader',
            options: {
                    sourceMap: false
            }
        },
        /* config.module.rule('scss').oneOf('normal').use('sass-loader') */
        {
            loader: 'sass-loader',
            options: {
                sourceMap: false,
                data: '@import "@/scss/_variables.scss";@import "@/scss/_mixins.scss";'
            }
        }
        ]
}

注意:

  1. webpack打包的时候按照数组从后往前的顺序将资源交给loader处理,因为最后生效的 style-loader 放前面。

  2. 关于PostCSS的处理

    1. postcss-loader 将PostCSS与Webpack连接,在根目录下创建 postcss.config.js.

    2. Autoprefixer:根据caniuse.com的数据,决定是否给css增加前缀

    3. stylelint: CSS 代码质量检测工具(语法错误,重复属性)

    4. CSSNext:使用最新的CSS语法特性

    5. CSS Module:CSS模块化

      1. 每个CSS文件中的样式拥有单独的作用域,不会和外界发生命名冲突。
      2. 对CSS进行依赖管理,可以通过相对路径引入CSS文件
      3. 通过compose轻松复用其他CSS模块
      {
            test: /\.css$/,
            use: [
                    'style-loader',
                    {
                            loader: 'css-loader',
                            options: {
                                    modules: true,
                                    localIdentName: '[name]__[local]__[hash:base64:5]'
                            }
                    }
            ]
      }
      

postcss.config.js内容

const autoprefixer = require('autoprefixer');
const stylelint = require('stylelint');

module.exports = {
     plugins: [
             autoprefixer({
                     grid: true,
                     browsers: ['> 1%', 'last 3 versions', 'android 4.2', 'ie 8']
             }),
             stylelint({
                     config: {
                             rules: {
                                     'declaration-no-important': true
                             }
                     }
             })
     ]
}

3. babel-loader

babel-loader 处理ES6+编译为ES5。

与此同时,还需要下载几个包:

babel-loader:Babel与Webpack协同工作的模块(起连接作用)。

@babel/core:Babel编译器的核心模块。

@babel/preset-env:Babel官方推荐的预置器,可根据用户设置的目标环境自动添加所需的插件和补丁编译ES6+代码。

{
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
                loader: 'babel-loader',
                options: {
                        cacheDirectory: true,
                        preset: [
                                ['env', { module: false }]
                        ]
                }
        }
}

注意:
1. babel-loader 对所有JS后缀文件设置规则,需要在exclude中添加node_modules,提升打包速度。
2. 使用cacheDirectory配置,启用缓存机制,避免未改变过的模块二次编译。
3. @babel/preset-env 将ES6 Module转化为CommonJS,导致Webpack的tree-shaking特性失效,将modules设置为false,禁用模块语句转化,将ES6 Module的语法交给Webpack本身处理。
4. babel-loader 支持从.babelrc文件读取babel配置,将presets和plugins从webpack配置文件读取出来,达到同样效果。

4. file-loader

file-loader 用于处理打包文件类型的资源,返回其publicPath。

{
        test: /\.(png|jpe?g|gif|webp)$/,
        use: [
                {
                        loader: 'file-loader',
                        options: {
                                name: 'static/img/[name].[hash:8].[ext]',
                                publicPath: './otherPath/'  // 覆盖webpack.output.publicPath
                        }
                }
        ]
}

注意:
1. 如果没有设置webpack的output的publicPath值,返回 文件名
2. 如果设置webpack的output的publicPath值,返回 webpack.output.publicPath+文件名

5. url-loader

url-loaderfile-loader 功能类似,但是可以 设置阈值,小于该阈值则返回对应文件的base64编码

{
        test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 4096,
                fallback: {
                    loader: 'file-loader',
                    options: {
                        name: 'static/img/[name].[hash:8].[ext]'
                    }
                }
            }
        }
    ]
}

注意:
1. 设置了limit属性,值为4096,当图片大小超过4kb的时候,会被转为base64的格式

6. vue-loader

vue-loader 处理vue组件。

但是,还需要

vue-template-compiler 编译Vue模版

sass-loader 处理sass/scss

css-loader 处理css样式

{
        test: /\.vue$/,
        use: 'vue-loader'
}

5. Plugins

5.1 VueLoaderPlugin

Vue-loader必须配合VueLoaderPlugin插件才能正常工作。

5.2 DefinePlugin

创建一个在编译时可以配置的全局常量

5.3 HotModuleReplacementPlugin

模块热替换插件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容