diveDylan / blog

My blog, detail is in the issues list
2 stars 0 forks source link

Vue-cli 初体验(二) splitChunks、preload、workbox #4

Open diveDylan opened 5 years ago

diveDylan commented 5 years ago

基本上一天把项目上需要用到的webpack手撸了一遍。涉及splitChunkspreloadworkbox

splitChunks

webpack chunk它内置的代码分割策略是这样的:

我们实际开发中处理chunk往往是一些不容易发生变更的文件、引用次数较多:node_modules、全局公用组件、一些函数等

// vue-config.js
chainWebpack: config => {
// split chunks
      config.
        when(process.env.NODE_ENV !== 'development', config => {
          config
            .optimization.splitChunks({ // https://webpack.js.org/plugins/split-chunks-plugin/#splitchunkschunks
              chunks: 'all', //  Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: /[\\/]src[\\/]components[\\/]Base[A-Z]\w+\.(vue|js)$/, // only base components
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true // If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can impact the resulting file name of the chunk.
                },
                date: {
                  name: 'chunk-date',
                  test: resolve('src/lib'), // date picker lib
                  priority: 4,
                  reuseExistingChunk: true 
                }
              }
            })
        })
}

preload or prefetch

@vue/preload-webpack-plugin

另一个解决方案代码:

// @rewrite webpack setting
  chainWebpack: config => {
    // preload the chunks split by u self
    config.plugins('preload')
      .tap(options => {
        // for import() lazy routes use initial https://github.com/vuejs/preload-webpack-plugin
        options.include = 'initial'
        // or split chunks at the bottom
        // options.include = ['chunk-libs', 'chunk-elementUI', 'chunk-commons', 'chunk-date']
        return options
      })
    // remove the prefetch plugin
    config.plugins.delete('prefetch')
}

work box

这个是service woker的一个插件,具体用法查看官方文档也可以查阅pwa相关资料

  configureWebpack: {
    plugin: [
      // for workbox service worker
      new GenerateSW({ 
        swDest: './sw.js',
        // importWorkboxFrom: 'local',
        skipWaiting: true,  
        clientsClaim: true,
        runtimeCaching: [{
          // Match any same-origin request that contains 'api'.
          urlPattern: /api/,
          // Apply a network-first strategy.
          handler: 'networkFirst',
          options: {
            // Fall back to the cache after 10 seconds.
            networkTimeoutSeconds: 10,
            // Use a custom cache name for this route.
            cacheName: 'my-api-cache',
            // Configure custom cache expiration.
            expiration: {
              maxEntries: 5,
              maxAgeSeconds: 60,
            },
            // Configure which responses are considered cacheable.
            cacheableResponse: {
              statuses: [0, 200],
              headers: {'x-test': 'true'},
            },
            // Configure the broadcast cache update plugin.
            broadcastUpdate: {
              channelName: 'my-update-channel',
            },
            // Add in any additional plugin logic you need.
            // plugins: [
            //   {cacheDidUpdate: () => /* custom plugin code */}
            // ],
          },
        }]
      })
    ]
  },