控制Webpack 3捆绑/分块(在Ionic3中)

5
我有很多东西在node_modules里,据我所知,当我构建我的Ionic3项目时,所有这些都最终出现在vendor.js中。为简单起见,假设我在node_modules中有以下文件夹:abc,xyz,uvw和qrs。进一步假设abc和xyz是公共库,但uvw和qrs是私有库。因此,我不想以一个包含所有四个库的单个vendor.js结束。相反,我想要以一个包含abc和xyz的vendor.js 为结果,以及一个包含uvw和qrs的private.js
我如何修改我的Ionic3项目中的配置文件来实现这个结果?理想情况下,我只需要在配置中命名uvw和qrs,并让默认行为生成'node_modules'中的“其他所有内容”的vendor.js即可。 更新: 值得参考的是,Ionic3.9.2使用Webpack3.10.0,Ionic webpack的默认配置如下。我真正关心的只是生产构建执行我上述描述行为。
/*
 * The webpack config exports an object that has a valid webpack configuration
 * For each environment name. By default, there are two Ionic environments:
 * "dev" and "prod". As such, the webpack.config.js exports a dictionary object
 * with "keys" for "dev" and "prod", where the value is a valid webpack configuration
 * For details on configuring webpack, see their documentation here
 * https://webpack.js.org/configuration/
 */

var path = require('path');
var webpack = require('webpack');
var ionicWebpackFactory = require(process.env.IONIC_WEBPACK_FACTORY);

var ModuleConcatPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
var PurifyPlugin = require('@angular-devkit/build-optimizer').PurifyPlugin;

var optimizedProdLoaders = [
  {
    test: /\.json$/,
    loader: 'json-loader'
  },
  {
    test: /\.js$/,
    loader: [
      {
        loader: process.env.IONIC_CACHE_LOADER
      },

      {
        loader: '@angular-devkit/build-optimizer/webpack-loader',
        options: {
          sourceMap: true
        }
      },
    ]
  },
  {
    test: /\.ts$/,
    loader: [
      {
        loader: process.env.IONIC_CACHE_LOADER
      },

      {
        loader: '@angular-devkit/build-optimizer/webpack-loader',
        options: {
          sourceMap: true
        }
      },

      {
        loader: process.env.IONIC_WEBPACK_LOADER
      }
    ]
  }
];

function getProdLoaders() {
  if (process.env.IONIC_OPTIMIZE_JS === 'true') {
    return optimizedProdLoaders;
  }
  return devConfig.module.loaders;
}

var devConfig = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.ts', '.js', '.json'],
    modules: [path.resolve('node_modules')]
  },

  module: {
    loaders: [
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.ts$/,
        loader: process.env.IONIC_WEBPACK_LOADER
      }
    ]
  },

  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),
    ionicWebpackFactory.getCommonChunksPlugin()
  ],

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
};

var prodConfig = {
  entry: process.env.IONIC_APP_ENTRY_POINT,
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

  resolve: {
    extensions: ['.ts', '.js', '.json'],
    modules: [path.resolve('node_modules')]
  },

  module: {
    loaders: getProdLoaders()
  },

  plugins: [
    ionicWebpackFactory.getIonicEnvironmentPlugin(),
    ionicWebpackFactory.getCommonChunksPlugin(),
    new ModuleConcatPlugin(),
    new PurifyPlugin()
  ],

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }
};


module.exports = {
  dev: devConfig,
  prod: prodConfig
}

你的ionic-app-scripts版本是多少? - Khurshid Ansari
根据我的项目中的./node_modules/@ionic/app-scripts/package.json文件,版本为3.1.9;当然可以按照https://dev59.com/C1gR5IYBdhLWcg3wRbo1的方式扩展Ionic webpack配置。 - vicatcu
1个回答

3
如果您正在使用webpack v4,则optimization.splitChunks.cacheGroups就是您要找的。完整文档在这里
现在好像OP想手动选择哪个模块放到哪个包中。 这是您可以实现它的方法:
  1. 添加两个新的cacheGroups,比如optimization.splitChunks.cacheGroups.vendor.private
  2. 设置filenameenforcetest字段
cacheGroups.vendor = {
  filename: 'vendor.js',
  enforce: true,
  test: (module) => {
    const vendorList = ['abc', 'xyz']
    return vendorList.includes(module.name)
  }
}

// Similar config for `cacheGroups.private`

事实证明,webpack版本3.10.0与Ionic 3.9.2兼容...这会改变什么吗? - vicatcu
我已经更新了问题,提供Ionic 3.9.2的默认webpack配置作为参考。 - vicatcu
Webpack 3有类似的功能吗? - vicatcu
@vicatcu webpack 3 我不确定,我知道 commonChunkPlugin 存在,但不是很确定它的工作原理。现在甚至在官方网站上都找不到 v3 的文档。这里 是 v3 文档的镜像。 - hackape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接