您的位置:新葡亰496net > 新葡亰官网 > 构建打包优化_javascript技巧_脚本之家,配置最佳

构建打包优化_javascript技巧_脚本之家,配置最佳

发布时间:2019-11-24 05:20编辑:新葡亰官网浏览(110)

    Webpack 4 配置最好实行

    2018/06/22 · JavaScript · webpack

    原稿出处: Zindex   

    Webpack 4 公布已经有大器晚成段时间了。Webpack 的版本号已经到来了 4.12.x。但因为 Webpack 官方还并未有形成搬迁指南,在文书档案层面上还具有欠缺,超过八分之四人对提高 Webpack 照旧没头没脑。

    唯独 Webpack 的付出公司已经写了大器晚成部分碎片的文章,官英特网也是有了新版配置的文档。社区中一些开辟者也曾经成功试水,进级到了 Webpack 4,並且总括成了博客。所以自个儿也终究去领悟了 Webpack 4 的具体意况。以下便是本身对搬迁到 Webpack 4 的意气风发部分经验。

    本文的主要在:

    • Webpack 4 在布署上带给了怎么样便利?要搬迁需求改过配置文件的什么内容?
    • 在此以前的 Webpack 配置最好试行在 Webpack 4 这几个本子,还适用吗?

    本文介绍了React Webpack 营造打包优化,分享给我们,具体如下:

    var path = require('path')
    var utils = require('./utils')
    var webpack = require('webpack')
    var config = require('../config')
    var merge = require('webpack-merge')
    var baseWebpackConfig = require('./webpack.base.conf')
    var HtmlWebpackPlugin = require('html-webpack-plugin')

    Wechat公众号头阵!那边小说制版大概不佳,请关怀公众号,查看历史音讯!

    Webpack 4 早前的 Webpack 最好实施

    这里以 Vue 官方的 Webpack 模板 vuejs-templates/webpack 为例,说说 Webpack 4 此前,社区里相比较早熟的 Webpack 配置文件是何等组织的。

    利用 babel-react-optimize 对 React 代码举办优化

    // 用于从webpack生成的bundle中提取文本到特定文件中的插件
    // 能够抽出出css,js文件将其与webpack输出的bundle抽离

    新葡亰496net 1

    分别开垦和生育景况

    粗粗的目录结构是如此的:

    build config src

    1
    2
    3
    build
    config
    src

    在 build 目录下有八个 webpack 的布置。分别是:

    • webpack.base.conf.js
    • webpack.dev.conf.js
    • webpack.prod.conf.js
    • webpack.test.conf.js

    那分别对应开荒、临盆和测量试验碰着的布置。在那之中 webpack.base.conf.js 是有个别公家的布局项。我们利用 webpack-merge 把那么些公共配置项和条件特定的配置项 merge 起来,成为三个整机的配备项。譬喻 webpack.dev.conf.js 中:

    'use strict' const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const devWebpackConfig = merge(baseWebpackConfig, { ... })

    1
    2
    3
    4
    5
    6
    7
    'use strict'
    const merge = require('webpack-merge')
    const baseWebpackConfig = require('./webpack.base.conf')
     
    const devWebpackConfig = merge(baseWebpackConfig, {
       ...
    })

    那四个条件不止有生机勃勃对安顿分裂,更器重的是,每种配置中用 webpack.DefinePlugin 向代码注入了 NODE_ENV 那么些意况变量。

    其大器晚成变量在区别条件下有分裂的值,举个例子 dev 意况下便是development。这个景况变量的值是在 config 文件夹下的配备文件中定义的。Webpack 首先从配置文件中读取那些值,然后注入。比方那样:

    build/webpack.dev.js

    plugins: [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env.js') }), ]

    1
    2
    3
    4
    5
    plugins: [
      new webpack.DefinePlugin({
        'process.env': require('../config/dev.env.js')
      }),
    ]

    config/dev.env.js

    module.exports ={ NODE_ENV: '"development"' }

    1
    2
    3
    module.exports ={
      NODE_ENV: '"development"'
    }

    有关分化条件下意况变量具体的值,比方开荒条件是 development,分娩条件是 production,其实是大家相沿成习的。

    框架、库的笔者,或然是我们的政工代码里,都会有部分依照情状做判断,试行不豆蔻梢头逻辑的代码,譬喻那样:

    if (process.env.NODE_ENV !== 'production') { console.warn("error!") }

    1
    2
    3
    if (process.env.NODE_ENV !== 'production') {
      console.warn("error!")
    }

    这一个代码会在代码压缩的时候被预实行一回,然后风华正茂旦条件表明式的值是 true,那这些 true 分支里的从头到尾的经过就被移除了。那是后生可畏种编写翻译时的死代码优化。这种不同不一样的条件,并给情状变量设置分歧的值的试行,让大家张开了编写翻译时按情况对代码举行针对优化的或许。

    自己商酌并未有接受的库,去除 import 援引

    var ExtractTextPlugin = require('extract-text-webpack-plugin')

    新葡亰496net 2

    Code Splitting && Long-term caching

    Code Splitting 平常要求做那些事情:

    • 为 Vendor 单独包装(Vendor 指第三方的库或然国有的幼功构件,因为 Vendor 的生成相当少,单独打包利于缓存卡塔尔
    • 为 Manifest (Webpack 的 Runtime 代码卡塔尔单独包装
    • 为分歧入口的公物事务代码打包(同理,也是为了缓存和加载速度卡塔尔国
    • 为异步加载的代码打八个国有的包

    Code Splitting 日常是因此配备 CommonsChunkPlugin 来成功的。叁个名列前茅的安插如下,分别为 vendor、manifest 和 vendor-async 配置了 康芒斯ChunkPlugin。

    new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { return ( module.resource && /.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }),

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
        new webpack.optimize.CommonsChunkPlugin({
          name: 'vendor',
          minChunks (module) {
            return (
              module.resource &&
              /.js$/.test(module.resource) &&
              module.resource.indexOf(
                path.join(__dirname, '../node_modules')
              ) === 0
            )
          }
        }),
     
        new webpack.optimize.CommonsChunkPlugin({
          name: 'manifest',
          minChunks: Infinity
        }),
     
        new webpack.optimize.CommonsChunkPlugin({
          name: 'app',
          async: 'vendor-async',
          children: true,
          minChunks: 3
        }),

    CommonsChunkPlugin 的性状就是布局相比难懂,我们的布置往往是复制过来的,这么些代码基本上成了模版代码(boilerplate卡塔尔。若是Code Splitting 的渴求轻便倒好,即使有比较奇特的供给,比方把差异入口的 vendor 打分裂的包,这就很难安顿了。不问可见配置 Code Splitting 是三个相比优伤的业务。

    而 Long-term caching 计谋是如此的:给静态文件多少个非常短的缓存过期时光,举例一年。然后在给文件名里加上三个hash,每一趟营造时,当文件内容更换时,文件名中的 hash 也会变动。浏览器在依照文件名作为文件的标志,所以当 hash 更改时,浏览器就能够再也加载那个文件。

    Webpack 的 Output 选项中能够安插文件名的 hash,譬喻这样:

    output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') },

    1
    2
    3
    4
    5
    output: {
      path: config.build.assetsRoot,
      filename: utils.assetsPath('js/[name].[chunkhash].js'),
      chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
    },

    按需打包所用的类库,比方 lodash 、 echart 等

    var env = process.env.NODE_ENV === 'testing'
    ? require('../config/test.env')
    : config.build.env

    本学科总共7篇,天天更新风流浪漫篇,请关心大家!你能够进去历史新闻查看未来作品,也敬请期待大家的新随笔!

    Webpack 4 下的一流施行

    lodash 能够行使babel-plugin-lodash 举办优化。

    // 归总基本功的webpack配置
    var webpackConfig = merge(baseWebpackConfig, {
    module: {
    rules: utils.styleLoaders({
    sourceMap: config.build.productionSourceMap,
    extract: true
    })
    },

    1.React多页面使用1(webpack开荒意况搭建,包括Babel、热更新等) ----2017.12.28

    Webpack 4 的变与不改变

    Webpack 4 这一个本子的 API 有后生可畏对 breaking change,但不意味说这么些版本就爆发了倾覆的改造。其实变化的点只有几个。况且只要您留神打听了那几个变化,你确定会歌唱。

    搬迁到 Webpack 4 也只必要检查一下 checklist,看看那一个点是还是不是都隐蔽到了,就足以了。

    在 babel-react-optimize 中接收了 babel-plugin-transform-react-remove-prop-types 那么些插件。平时景况下,假设您在代码中从不援用到构件的 PropTypes ,则一心没难题。就算你的机件用到了,那么使用该插件或然会招致难题。

    devtool: config.build.productionSourceMap ? '#source-map' : false,
    // 配置webpack的输出
    output: {
    // 编写翻译输出目录
    path: config.build.assetsRoot,
    // 编译输出文件名格式
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    // 没有一些名输著名的文书输出的文本名格式
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
    },

    2.React多页面应用2(管理CSS及图片,引进postCSS及图片管理等)----2017.12.29

    支付和生育条件的差异

    Webpack 4 引入了 mode 这一个选项。那么些选项的值能够是 development 或许 production。

    设置了 mode 之后会把 process.env.NODE_ENV 也安装为 development 或然production。然后在 production 方式下,会暗中同意开启 UglifyJsPlugin 等等一群插件。

    Webpack 4 协理零布署使用,可以从命令行钦赐 entry 的地点,假使不点名,就是 src/index.js。mode 参数也能够从命令行参数字传送入。那样局地常用的临蓐条件打包优化都能够直接启用。

    我们须要在乎,Webpack 4 的零配置是有限度的,如若要拉长本人想加的插件,或然要加四个entry,依旧供给二个安排文件。

    即使如此,Webpack 4 在各类方面都做了全力,努力让零配置能够做的业务越多。这种内置优化的艺术使得大家在品种运营的时候,能够把主要精力放在职业花费上,等前期业务变复杂过后,才须要关怀配置文件的编排。

    在 Webpack 4 推出 mode 这些选项以前,即使想要为不相同的开拓条件构建差别的营造选项,大家一定要通过确立四个Webpack 配置且分别设置分歧的条件变量值这种方法。那也是社区里的精品实行。

    Webpack 4 推出的 mode 选项,其实是后生可畏种对社区中精品实行的收到。这种思路作者是很同情的。开源项目来自于社区,在社区中成长,从社区中选拔营养,然后回报社区,那是贰个良性循环。近来自身在众多前端项目中都来看了相似的趋向。接下来要讲的任何多少个Webpack 4 的特色也是和社区的申报离不开的。

    那就是说上文中介绍的选拔三个 Webpack 配置,以至手动景况变量注入的法子,是还是不是在 Webpack 4 下就不适用了吧?并不是那样。在Webpack 4 下,对于八个自爱的档期的顺序,我们依旧亟待两个差异的配置文件。要是大家对为测量试验景况的打包做一些出奇管理,我们还亟需在足够配置文件里用 webpack.DefinePlugin 手动注入 NODE_ENV 的值(比如 test)。

    Webpack 4 下豆蔻梢头旦急需三个 test 境遇,那 test 蒙受的 mode 也是 development。因为 mode 唯有付出和生育三种,测量试验意况应该是归于开拓阶段。

    // 配置webpack插件

    3.React多页面使用3(webpack品质进步,包涵打包质量、提取公共包等)----2017.12.30

    其三方库 build 的选用

    在 Webpack 3 时代,我们必要在生养条件的的 Webpack 配置里给第三方库设置 alias,把那一个库的门道设置为 production build 文件的门道。以此来引进生产版本的信赖。

    比如那样:

    resolve: { extensions: [".js", ".vue", ".json"], alias: { vue$: "vue/dist/vue.runtime.min.js" } },

    1
    2
    3
    4
    5
    6
    resolve: {
      extensions: [".js", ".vue", ".json"],
      alias: {
        vue$: "vue/dist/vue.runtime.min.js"
      }
    },

    在 Webpack 4 引进了 mode 之后,对于一些依赖,我们能够绝不配置 alias,比如 React。React 的进口文件是如此的:

    'use strict'; if (process.env.NODE_ENV === 'production') { module.exports = require('./cjs/react.production.min.js'); } else { module.exports = require('./cjs/react.development.js'); }

    1
    2
    3
    4
    5
    6
    7
    'use strict';
     
    if (process.env.NODE_ENV === 'production') {
      module.exports = require('./cjs/react.production.min.js');
    } else {
      module.exports = require('./cjs/react.development.js');
    }

    如此那般就贯彻了 0 配置活动采纳临盆 build。

    但大多的第三库并不曾做这一个进口的条件剖断。所以这种景色下大家照旧须求手动配置 alias。

    Webpack 营造打包优化

    plugins: [
    //
    new webpack.DefinePlugin({
    'process.env': env
    }),

    4.React多页面应用4(webpack自动化生成多入口页面)----2017.12.31

    Code Splitting

    Webpack 4 下还应该有一个大转移,正是扬弃了 CommonsChunkPlugin,引进了 optimization.splitChunks 这几个选项。

    optimization.splitChunks 暗中认可是不用安装的。倘使 mode 是 production,那Webpack 4 就能够打开 Code Splitting。

    暗中认可 Webpack 4 只会对按需加载的代码做分割。借使大家须求配备最早加载的代码也投入到代码分割中,能够安装 splitChunks.chunks 为 ‘all’。

    Webpack 4 的 Code Splitting 最大的特性便是安插轻巧(0配置起步卡塔 尔(阿拉伯语:قطر‎,和传说内置准则自动拆分。内置的代码切分的平整是那样的:

    • 新 bundle 被八个及以上模块援用,或然来自 node_modules
    • 新 bundle 大于 30kb (压缩在此以前卡塔尔
    • 异步加载并发加载的 bundle 数不能够超过 5 个
    • 始发加载的 bundle 数不可能超越 3 个

    简轻松单的说,Webpack 会把代码中的公共模块自动抽取来,变成叁个包,前提是以此包大于 30kb,不然Webpack 是不会挤出公共代码的,因为增添一回呼吁的工本是不可能忽略的。

    具体的业务场景下,具体的拆分逻辑,能够看 SplitChunksPlugin 的文档以及 webpack 4: Code Splitting, chunk graph and the splitChunks optimization 那篇博客。这两篇文章基本陈列了具有也许现身的景况。

    大器晚成旦是平凡的接纳,Webpack 4 内置的不成方圆就足足了。

    假假若新鲜的供给,Webpack 4 的 optimization.splitChunks API也足以满意。

    splitChunks 有一个参数叫 cacheGroups,那些参数相符事先的 CommonChunks 实例。cacheGroups 里每个对象就是三个顾客定义的 chunk。

    后面大家讲到,Webpack 4 内置有生龙活虎套代码分割的平整,那客户也足以自定义 cacheGroups,也正是自定义 chunk。那四个 module 应该被抽到哪个 chunk 呢?那是由 cacheGroups 的收取范围调控的。种种 cacheGroups 都能够定义本人抽出模块的节制,相当于如何文件中的公共代码会收取到自个儿这么些chunk 中。不一样的 cacheGroups 之间的模块范围要是有混合,大家能够用 priority 属性调整优先级。Webpack 4 默许的抽出的优先级是低于的,所以模块会优先被抽出到顾客的自定义 chunk 中。

    splitChunksPlugin 提供了三种调控 chunk 抽出模块范围的法子。生龙活虎种是 test 属性。那脾脾性能够流传字符串、正则或许函数,全体的 module 都会去相配test 传入的标准,假诺基准切合,就被放入那一个 chunk 的预备模块范围。若是大家传入的准绳是字符串或然正则,那匹配的流水线是那样的:首先相配module 的路径,然后相配 module 以前所在 chunk 的 name。

    比方我们想把全部 node_modules 中引进的模块打包成二个模块:

    vendors1: { test: /[/]node_modules[/]/, name: 'vendor', chunks: 'all', }

    1
    2
    3
    4
    5
      vendors1: {
        test: /[/]node_modules[/]/,
        name: 'vendor',
        chunks: 'all',
      }

    因为从 node_modules 中加载的依附路线中都满含node_modules,所以这几个正则会合作全数从 node_modules 中加载的依附。

    test 属性能够以 module 为单位决定 chunk 的收取范围,是意气风发种细粒度比较小的章程。splitChunksPlugin 的第三种调节抽取模块范围的艺术便是 chunks 属性。chunks 能够是字符串,例如 ‘all’|’async’|’initial’,分别表示了总体 chunk,按需加载的 chunk 以至开端加载的 chunk。chunks 也足以是多少个函数,在这里个函数里大家能够拿到chunk.name。那给了我们经过输入来划分代码的技巧。这是生机勃勃种细粒度非常大的措施,以 chunk 为单位。

    举个例证,举例大家有 a, b, c 多个输入。我们期望 a,b 的公物代码单独打包为 common。也正是说 c 的代码不参预国有代码的分开。

    作者们得以定义叁个 cacheGroups,然后设置 chunks 属性为二个函数,那一个函数担当过滤那么些 cacheGroups 包括的 chunk 是何许。示例代码如下:

    optimization: { splitChunks: { cacheGroups: { common: { chunks(chunk) { return chunk.name !== 'c'; }, name: 'common', minChunks: 2, }, }, }, },

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      optimization: {
        splitChunks: {
          cacheGroups: {
            common: {
              chunks(chunk) {
                return chunk.name !== 'c';
              },
              name: 'common',
              minChunks: 2,
            },
          },
        },
      },

    地方配置的意思正是:大家想把 a,b 入口中的公共代码单独打包为多少个名为common 的 chunk。使用 chunk.name,我们得以轻便的做到那些要求。

    在地方的处境中,大家清楚 chunks 属性能够用来按入口切分几组公共代码。以后大家来看二个有一点复杂一些的场所:对分裂分组入口中引进的 node_modules 中的信赖进行分组。

    诸如大家有 a, b, c, d 多少个入口。我们意在 a,b 的信任打包为 vendor1,c, d 的信赖打包为 vendor2。

    其意气风发须求须要大家对进口和模块都做过滤,所以大家须求接受 test 属性那一个细粒度十分小的章程。我们的思绪正是,写多个 cacheGroup,一个cacheGroup 的论断规范是:假使 module 在 a 大概 b chunk 被引入,何况module 的路线包蕴 node_modules,那这几个 module 就应该被打包到 vendors第11中学。 vendors2 同理。

    vendors1: { test: module => { for (const chunk of module.chunksIterable) { if (chunk.name && /(a|b)/.test(chunk.name)) { if (module.nameForCondition() && /[/]node_modules[/]/.test(module.nameForCondition())) { return true; } } } return false; }, minChunks: 2, name: 'vendors1', chunks: 'all', }, vendors2: { test: module => { for (const chunk of module.chunksIterable) { if (chunk.name && /(c|d)/.test(chunk.name)) { if (module.nameForCondition() && /[/]node_modules[/]/.test(module.nameForCondition())) { return true; } } } return false; }, minChunks: 2, name: 'vendors2', chunks: 'all', }, };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
      vendors1: {
        test: module => {
          for (const chunk of module.chunksIterable) {
                if (chunk.name && /(a|b)/.test(chunk.name)) {
                    if (module.nameForCondition() && /[/]node_modules[/]/.test(module.nameForCondition())) {
                     return true;
                 }
                }
           }
          return false;
        },
        minChunks: 2,
        name: 'vendors1',
        chunks: 'all',
      },
      vendors2: {
        test: module => {
          for (const chunk of module.chunksIterable) {
                if (chunk.name && /(c|d)/.test(chunk.name)) {
                    if (module.nameForCondition() && /[/]node_modules[/]/.test(module.nameForCondition())) {
                     return true;
                 }
                }
           }
          return false;
        },
        minChunks: 2,
        name: 'vendors2',
        chunks: 'all',
      },
    };

    Webpack 创设打包存在的主题素材主要性聚焦于下边多个地点:

    // 丑化压缩代码
    new webpack.optimize.UglifyJsPlugin({
    compress: {
    warnings: false
    },
    sourceMap: true
    }),

    5.React多页面使用5(webpack临盆条件布署,包含压缩js代码,图片转码等)----2018.01.01

    Long-term caching

    Long-term caching 这里,基本的操作和 Webpack 3 是相似的。然则 Webpack 3 的 Long-term caching 在操作的时候,有个小意思,那几个主题材料是关于 chunk 内容和 hash 变化不相同等的:

    在国有代码 Vendor 内容不改变的情状下,加多 entry,或许 external 注重,也许异步模块的时候,Vendor 的 hash 会改造

    后边 Webpack 官方的专辑里面有黄金年代篇小说讲这些主题材料:Predictable long term caching with Webpack。给出了两个解决方案。

    本条方案的骨干正是,Webpack 内部维护了叁个自增的 id,各样 chunk 都有一个id。所以当增添 entry 可能别的类型 chunk 的时候,id 就能够变动,引致内容从未调换的 chunk 的 id 也发出了转移。

    对此大家的回答方案是,使用 webpack.NamedChunksPlugin 把 chunk id 变为三个字符串标志符,那个字符包日常正是模块的相对路线。那样模块的 chunk id 就足以稳固下来。

    新葡亰496net 3

    这里的 vendors1 就是 chunk id

    HashedModuleIdsPlugin 的效劳和 NamedChunksPlugin 是千篇意气风发律的,只不过 HashedModuleIdsPlugin 把根据模块相对路线生成的 hash 作为 chunk id,那样 chunk id 会越来越短。由此在生育中更推荐用 HashedModuleIdsPlugin。

    那篇作品说还讲到,webpack.NamedChunksPlugin 只可以对经常的 Webpack 模块起效果,异步模块,external 模块是不会起功用的。

    异步模块能够在 import 的时候增加 chunkName 的讲授,比如那样:import(/ webpackChunkName: “lodash” / ‘lodash’).then() 那样就有 Name 了

    于是大家供给再使用叁个插件:name-all-modules-plugin

    本条插件中用到部分老的 API,Webpack 4 会发出警报,这么些 pr 有新的本子,不过小编不自然会 merge。大家运用的时候能够平昔 copy 那一个插件的代码到我们的 Webpack 配置内部。

    做了这几个干活儿之后,大家的 Vendor 的 ChunkId 就再也不会爆发不应该发生的改动了。

    Webpack 创设速度慢 Webpack 打包后的文件体量过大

     

    6.React多页面使用6(gulp自动化公布到八个条件,生成版本号,打包成zip等)----2018.01.02

    总结

    Webpack 4 的改观主就算对社区中特级施行的接纳。Webpack 4 通过新的 API 大大进级了 Code Splitting 的体验。但 Long-term caching 中 Vendor hash 的主题材料或然不曾缓慢解决,供给手动配置。本文首要介绍的便是 Webpack 配置最棒施行在 Webpack 3.x 和 4.x 背景下的争论。希望对读者的 Webpack 4 项指标安插文件协会有所扶助。

    另外,推荐 SURVIVEJS – WEBPACK 这么些在线教程。那几个课程总计了 Webpack 在骨子里开垦中的实行,而且把材质更新到了新式的 Webpack 4。

    1 赞 4 收藏 评论

    新葡亰496net 4

    Webpack 营造速度慢

    // 抽离css文件
    new ExtractTextPlugin({
    filename: utils.assetsPath('css/[name].[contenthash].css')
    }),

    7.React多页面应用7(引进eslint代码检查)----2018.01.03

    可以应用 Webpack.DDLPlugin , HappyPack 来增加创设速度。具体参见小铭在 DMP DDLPlugin 的文书档案。原作如下:

     

    支出条件:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2

    Webpack.DLLPlugin

    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
    // see
    new HtmlWebpackPlugin({
    filename: process.env.NODE_ENV === 'testing'

    当大家项目页面越多,依赖更加的多,打包时间会越来越长,那么大家如优化呢?

    增长多少个 webpack.dll.config.js主若是用到贰个 DllPlugin 插件,把有些第三方的财富独立包装,同期内置二个 manifest.json 配置文件中,

    ? 'index.html'
    : config.build.index,
    template: 'index.html',
    inject: true,
    minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
    // more options:
    //
    },

    1.打包品质难题 (涉及众多要素,大家稳步来)

    如此在组件中立异后,就不会再也 build 这一个第三方的能源,

    // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    chunksSortMode: 'dependency'
    }),

    引进信任

    何况独立布署 dll/vendors.js 文件,提必要 webpack.dll.config.js 改正package.json

    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: function (module, count) {
    // any required modules inside node_modules are extracted to vendor

    npm i -D cache-loader

    在 scripts 中添加: "dll": "webpack --config webpack.dll.config.js --progress --colors ", 。

    return (
    module.resource &&
    /.js$/.test(module.resource) &&
    module.resource.indexOf(
    path.join(__dirname, '../node_modules')
    ) === 0
    )
    新葡亰496net,}
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated

    修改 webpack.dev.conf.js

    进行 npm run dll 将来,会在 dll 目录下临盆 多少个文本 vendor-manifest.json ,vendor.dll.js

    new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    chunks: ['vendor']
    })
    ]
    构建打包优化_javascript技巧_脚本之家,配置最佳实践。})

    const webpack =require('webpack');//引入webpack

    安顿 webpack.dev.config.js 文件,插足叁个 DllReferencePlugin 插件,并内定 vendor-manifest.json 文件

    // gzip格局下须要引进compression插件举办裁减
    if (config.build.productionGzip) {
    var CompressionWebpackPlugin = require('compression-webpack-plugin')
    webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
    asset: '[path].gz[query]',
    algorithm: 'gzip',
    test: new RegExp(
    '\.('
    config.build.productionGzipExtensions.join('|')
    ')$'
    ),

    const opn =require('opn');//张开浏览器

    new webpack.DllReferencePlugin({ context: join, manifest: require('./dll/vendor-manifest.json')})
    

    threshold: 10240,
    minRatio: 0.8
    })
    )
    }

    const merge =require('webpack-merge');//webpack配置文件合併

    专一,要求在 htmlWebpackPlugin 插件中布置 NODE_ENV 参数

    if (config.build.bundleAnalyzerReport) {
    var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    webpackConfig.plugins.push(new BundleAnalyzerPlugin())
    }

    const path =require("path");

    Happypack

    module.exports = webpackConfig

    const baseWebpackConfig =require("./webpack.base.conf");//功底配置

    由此多线程,缓存等方法提高 rebuild 功用

    const webpackFile =require("./webpack.file.conf");//一些路径配置

    在 webpack.dev.config.js 中针对不一致的能源创立多个 HappyPack, 比方 js 1 个,less 1 个,并设置好 id

    let config = merge(baseWebpackConfig, {

    new HappyPack({ id: 'js', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['babel-loader?babelrc&cacheDirectory=true'],}),new HappyPack({ id: 'less', threadPool: happyThreadPool, cache: true, verbose: true, loaders: ['css-loader', 'less-loader'],})
    

    output: {

    在 module.rules 中配置 use 为 happypack/loader, 设置 id

    path: path.resolve(webpackFile.devDirectory),

    { test: /.js$/, use: [ 'happypack/loader?id=js' ], exclude: /node_modules/}, { test: /.less$/, loader: extractLess.extract({ use: ['happypack/loader?id=less'], fallback: 'style-loader' })}
    

           filename:'js/[name].js',

    压缩 Webpack 打包后的文本体积大小

           chunkFilename:"js/[name]-[id].js",

    先是须要对大家全部 bundle 举行剖析,由哪些东西组成及各组成都部队分所占大小。

           publicPath:''

    此地推荐 webpack-bundle-analyzer 。安装后在 webpack.dev.config.js 中加上插件就能够,就能够在历次运行后自动在网址展开解析结果,如下图

       },

    plugins.push( new BundleAnalyzerPlugin;
    

       plugins: [

    而外,还是可以够将包装进程输出成json文件

    /*安装支出情形*/

    webpack --profile --json -> stats.json
    

           new webpack.DefinePlugin({

    下一场到上面那多少个网站开展拆解解析

    'process.env': {

    webpack/analyse Webpack Chart

    NODE_ENV: JSON.stringify('development'),

    因此地点的图形解析能够知晓得看看,整个 bundle.js 的组成都部队分及相应的深浅。

               }

    解决 bundle.js 体量过大的消除思路如下:

    }),

    生育情形启用压缩等插件,去除不要求插件 拆分业务代码与第三方库及公共模块 webpack 开启 gzip 压缩 按需加载

           /*安装热更新*/

    传延宗族条件启用压缩等插件,去除不须要插件

           new webpack.HotModuleReplacementPlugin(),

    作保在生产条件运转 webpack.DefinePlugin 和 webpack.optimize.UglifyJsPlugin 。

       ],

    const plugins = [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: false //eslint-disable-line } }) ]
    

       module: {

    拆分业务代码与第三方库及集人体模型块

    rules: [

    鉴于类别的事务代码退换频率极高,而第三方库的代码变化则相对未有那么频率。借使将业务代码和第三库打包到同三个chunk 的话,在每一次创设的时候,哪怕业务代码只改了风度翩翩行,就算第三方库的代码未有产生变化,会导致整个 chunk 的 hash 跟上壹遍差异。那不是大家想要的结果。大家想要的是,若是第三方库的代码未有生成,那在营造的时候也要确认保证相应的 hash 未有爆发变化,进而能选择浏览器缓存,更加好的增加页面加载质量和浓缩页面加载时间。

    {

    为此得以将第三库的代码单独拆分成 vendor chunk,与事务代码抽离。那样即使业务代码再怎么产生变化,只要第三方库代码未有产生变化,对应的 hash 就不改变。

    test:/.(js|jsx)$/,

    先是 entry 配置三个 app 和 vendor 四个chunk

                   use: [

    entry: { vendor: [path.join(__dirname, 'dll', 'vendors.js')], app: [path.join(__dirname, 'src/index')]},output: { path: path.resolve, filename: '[name].[chunkhash:8].js'},
    

    'cache-loader',

    里头 vendros.js 是团结定义的什么样第三方库要求放入 vendor 中,如下:

                       'babel-loader',

    require;require;require;require;require;require;require;require;
    

                   ],

    接下来通过 CommonsChunkPlugin 拆分第三库

                   include: [

    plugins.push( // 拆分第三方库 new webpack.optimize.CommonsChunkPlugin, // 拆分 webpack 自身代码 new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', minChunks: Infinity }));
    

    path.resolve(__dirname, "../../app"),

    地点的配置有七个细节须求注意

                       path.resolve(__dirname, "../../entryBuild")

    使用 chunkhash 而不用 hash 单独拆分 webpack 本人代码

    ],

    使用 chunkhash 而不用 hash

                   exclude: [

    先来会见那二者有啥差距:

    path.resolve(__dirname, "../../node_modules")

    hash 是 build-specific ,任何四个文本的退换都会招致编写翻译的结果差别,适用于开采阶段 chunkhash 是 chunk-specific ,是基于每种 chunk 的始末总结出的 hash,适用于生产

    ],

    于是为了保障第三方库不改变的情景下,对应的 vendor.js 的 hash 也要维持不变,大家再 output.filename 中利用了 chunkhash

               },

    独立拆分 webpack 本身代码

               {

    Webpack 有个已知难点:

    test:/.(css|pcss)$/,

    webpack 自个儿的 boilerplate 和 manifest 代码恐怕在历次编写翻译时都会调换。

                   loader:'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',

    那形成我们只是在 入口文件 改了黄金年代行代码,但编写翻译出的 vendor 和 entry chunk 都变了,因为它们本人都蕴涵那某些代码。

                   exclude:/node_modules/

    那是不客观的,因为其实大家的第三方库的代码没变,vendor 不应该在我们业务代码变化时发生变化。

               },

    故此大家供给将 webpack 那后生可畏都部队分代码抽离剥离

               {

    new webpack.optimize.CommonsChunkPlugin({ name: "runtime", minChunks: Infinity}),
    

    test:/.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,

    里头的 name 只要不在 entry 就能够,平日使用 "runtime" 或 "manifest" 。

                   loader:'file-loader?name=[name].[ext]&outputPath=' webpackFile.resource '/'

    其余一个参数 minChunks 表示:在流传公共chunk 在此之前所供给包蕴的足足数量的 chunks。数量必得高于等于2,恐怕个别等于 chunks的数码,传入 Infinity 会登时生成 公共chunk,但里边未有模块。

               }

    越来越多关于 CommonChunkPlugin 能够查阅 官方文书档案

    ]

    拆分公共财富

    构建打包优化_javascript技巧_脚本之家,配置最佳实践。},

    同 下边包车型客车拆分第三方库同样,拆分公共财富得以将公用的模块单独打出二个chunk,你能够设置 minChunk 来抉择是共用略带次模块才将它们分离。配置如下:

       /*设置api转发*/

    new webpack.optimize.CommonsChunkPlugin({ name: 'common', minChunks: 2,}),
    

       devServer: {

    是还是不是需求举办这一步优化能够活动依据项指标事情复开支来剖断。

    host:'0.0.0.0',

    开启 gzip

           port:8080,

    接收 CompressionPlugin 插件开启 gzip 就能够:

           hot:true,

    // 添加 gzipnew CompressionPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: /.$/, threshold: 10240, minRatio: 0.8})
    

           inline:true,

    以上就是本文的全体内容,希望对大家的上学抱有助于,也目的在于我们多多点拨脚本之家。

           contentBase: path.resolve(webpackFile.devDirectory),

           historyApiFallback:true,

           disableHostCheck:true,

           proxy: [

    {

    context: ['/api/**', '/u/**'],

                   target:'',

                   secure:false

               }

    ],

           /*张开浏览器 并张开本项目网站*/

           after() {

    opn(':' this.port);

           }

    }

    });

    module.exports = config;

    增多了之类代码

    use: [

    'cache-loader',

       'babel-loader',

    ],

    大家看下效果

    从不引进 cache-loader

    打包时间

    引入 cache-loader

    包裹时间

    收缩了3秒,再页面比非常多的时候,优化是很扎眼的!

    2.领取公共包

    率先我们看下 首页 和 商号页 相像部分很区别部分

    差了一点相通,好! 我们领到公共部分,放入贰个零器件中

    我们在 app-> component -> common 目录下 新建 Seconds.jsx 公共组件

    import Reactfrom 'react';

    class Secondsextends React.Component {

    constructor(props) {

    super(props);

           this.state = {seconds:0};

       }

    tick() {

    this.setState(prevState => ({

    seconds: prevState.seconds 1

           }));

       }

    componentDidMount() {

    this.interval =setInterval(() =>this.tick(), 1000);

       }

    componentWillUnmount() {

    clearInterval(this.interval);

       }

    render() {

    return (

                       这是{this.props.title}

                       Seconds: {this.state.seconds}

           );

       }

    }

    export default Seconds;

    改造 首页

    import Reactfrom 'react';

    import '../../public/css/index.pcss'

    import Secondsfrom '../common/Seconds'

    const Index = () =>

    ;

    export default Index;

    更换商号页

    import Reactfrom 'react';

    import '../../public/css/shop.pcss'

    import Secondsfrom '../common/Seconds'

    const Index = () =>

    ;

    export default Index;

    npm run dev 运营看下 是不是符合规律

    一切平常

    3.上马提取

    目标是: 

    react react-dom 我们打包成 vendor.js  因为她俩是第三方部,差不离不会变,除非您升官

    组件的集体部分 大家打包成 common.js

    零器件独立的事情代码大家打包在对应的js文件中 如 index.js 或 shop.js

    改造 

    config -> webpack -> webpack.base.conf.js

    const json =require('../../package.json');//引进package.json

    const newEntry = {

    'index':'./entryBuild/index.js',

       'shop':'./entryBuild/shop.js',

    };

    newEntry.vendor = Object.keys(json.dependencies); //把 package.json dependencies字段的值放进 vendor中

    let config = {

    entry: newEntry,

       resolve: {

    extensions: [".js", ".json", ".jsx", ".css", ".pcss"],

       }

    };

    module.exports = config;

    改造 

    config -> webpack -> webpack.dev.conf.js

    const webpack =require('webpack');//引入webpack

    const opn =require('opn');//打开浏览器

    const merge =require('webpack-merge');//webpack配置文件归并

    const path =require("path");

    const baseWebpackConfig =require("./webpack.base.conf");//功底配置

    const webpackFile =require("./webpack.file.conf");//一些渠道配置

    let config = merge(baseWebpackConfig, {

    output: {

    path: path.resolve(webpackFile.devDirectory),

           filename:'js/[name].js',

           chunkFilename:"js/[name]-[id].js",

           publicPath:''

       },

       plugins: [

    /*设置开拓境况*/

           new webpack.DefinePlugin({

    'process.env': {

    NODE_ENV: JSON.stringify('development'),

               }

    }),

           /*安装热更新*/

           new webpack.HotModuleReplacementPlugin(),

           /* common 业务公共代码,vendor引进第三方 */

           new webpack.optimize.CommonsChunkPlugin({

    name: ["common", "vendor"],

           }),

           /* 防止 vendor hash 变化 */

    // extract webpack runtime and module manifest to its own file in order to

    // prevent vendor hash from being updated whenever app bundle is updated

           new webpack.optimize.CommonsChunkPlugin({

    name:'manifest',

               chunks: ['vendor']

    }),

       ],

       module: {

    rules: [

    {

    test:/.(js|jsx)$/,

                   use: [

    'cache-loader',

                       'babel-loader',

                   ],

                   include: [

    path.resolve(__dirname, "../../app"),

                       path.resolve(__dirname, "../../entryBuild")

    ],

                   exclude: [

    path.resolve(__dirname, "../../node_modules")

    ],

               },

               {

    test:/.(css|pcss)$/,

                   loader:'style-loader?sourceMap!css-loader?sourceMap!postcss-loader?sourceMap',

                   exclude:/node_modules/

               },

               {

    test:/.(png|jpg|gif|ttf|eot|woff|woff2|svg|swf)$/,

                   loader:'file-loader?name=[name].[ext]&outputPath=' webpackFile.resource '/'

               }

    ]

    },

       /*设置api转发*/

       devServer: {

    host:'0.0.0.0',

           port:8080,

           hot:true,

           inline:true,

           contentBase: path.resolve(webpackFile.devDirectory),

           historyApiFallback:true,

           disableHostCheck:true,

           proxy: [

    {

    context: ['/api/**', '/u/**'],

                   target:'',

                   secure:false

               }

    ],

           /*开荒浏览器 并开发本项目网站*/

           after() {

    opn(':' this.port);

           }

    }

    });

    module.exports = config;

    增加了如下代码

    /*设置热更新*/

    new webpack.HotModuleReplacementPlugin(),

    /* common 业务公共代码,vendor引进第三方 */

    new webpack.optimize.CommonsChunkPlugin({

    name: ["common", "vendor"],

    }),

    /* 防止 vendor hash 变化 */

    // extract webpack runtime and module manifest to its own file in order to

    // prevent vendor hash from being updated whenever app bundle is updated

    new webpack.optimize.CommonsChunkPlugin({

    name:'manifest',

       chunks: ['vendor']

    }),

    改造 index.html

       react1

    增多了之类代码

    注:顺序不可能变

    改造 shop.html

       react1

    新葡亰496net 5

    注:顺序无法变

    察觉未有 其实 index.html 和 shop.html  三个页面 很像 很像  是否?  大家会再前面自动化生成页面中 来化解那几个标题,就绝不手动去新建了!

    npm run dev 看下效果

    没领到以前

    新葡亰496net 6

    领取之后

    新葡亰496net 7

    一切平常

    新葡亰496net 8

    本文完

    新葡亰496net 9

    制止随便转发,如需转发请在大众号中留言联系大家!

    多谢童鞋们辅助!

    应接童鞋们留言!

    本文由新葡亰496net发布于新葡亰官网,转载请注明出处:构建打包优化_javascript技巧_脚本之家,配置最佳

    关键词:

上一篇:没有了

下一篇:没有了