ionic-team / ionic-app-scripts

App Build Scripts for Ionic Projects
http://ionicframework.com/
MIT License
608 stars 302 forks source link

webpack 3.0.1 - multi entry point is not working (up to 2.0.4 is working) #1296

Open ghost opened 6 years ago

ghost commented 6 years ago

Short description of the problem:

webpack.config.js - module export is ignored at all

What behavior are you expecting?

you can mess up the entry : {} of the module export, but it's not relying on it.

Steps to reproduce: package.json "config": { "ionic_webpack": "./config/webpack.config.js" }, "scripts": { "clean": "ionic-app-scripts clean", "build": "ionic-app-scripts build", "watch": "ionic-app-scripts watch", "ionic:build": "ionic-app-scripts build", "ionic:serve": "ionic-app-scripts serve", "serve:before": "watch", "emulate:before": "build", "deploy:before": "build", "build:before": "build", "run:before": "build", "run:after": "watch", "browser": "ionic-app-scripts serve --sourceMap source-map --iscordovaserve --wwwDir platforms/browser/www/ --buildDir platforms/browser/www/build", "test": "karma start ./test-config/karma.conf.js", "test-ci": "karma start ./test-config/karma.conf.js --single-run", "test-coverage": "karma start ./test-config/karma.conf.js --coverage", "e2e": "npm run e2e-update && npm run e2e-test", "e2e-test": "protractor ./test-config/protractor.conf.js", "e2e-update": "webdriver-manager update --standalone false --gecko false" },

scripts are not really used, as i'm building with "ionic cordova build browser", so no npm build is involved.

webpack.config.js

module.exports = {
entry: {
    main: process.env.IONIC_APP_ENTRY_POINT,
    rvt: '/../src/lib/ms-rvt/db',
    match: '/../src/lib/ms-match'
  },
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
    libraryTarget: 'var',
    library: '[name]'
  },...
}
insert any relevant code between the above and below backticks

Which @ionic/app-scripts version are you using? 3.0.1

Other information: (e.g. stacktraces, related issues, suggestions how to fix, stackoverflow links, forum links, etc) I have no idea, why it's not working, but for webworker i need code splitting with multi entry point (i need shared library).

There are many irrelevant info on the net, which are not working.

ghost commented 6 years ago

the main problem was, that the module.export has been changed to

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

so if you include any webpack_config in the package.json, you should use this, instead of module.exports = config, as it will be totally ignored

I want to share my extension, as it's useful, who are using external environment variables or webworker which needs shared libraries package.json

...
"config": {
"ionic_webpack": "./config/webpack.config.js"
}...

FAQ

webpack.config.js - it will work with appscript 3.0.1 - and typescript based webworkers

1, vendor.js is messing multiple entries around, so i commented out the getCommonChunksPlugin 2, you might need to add/update your webpack in dev dependencies, which is not there in ionic case default 3, if you don't use chunks:["rvt"] - it makes a corrupt some bytes file. 4, if you don't use CommonChunkPlugin, the rvt/match.js will be generated, but it throws webpackjsonp not found error, and the main.js will contain the rvt/match.js contents also > 5, Don't use file-loader if you are using webworkers - use worker-loader!!! source map file won't be generated in file-loader case, so you are not able to debug, but the functionality will work. I think the two project should be merged together to avoid confusions later on.

I just make this note, as the configuration even if it's easy it was horrific and i have wasted lots of time reading irrelevant infos on forums.

Suggestion

1) I think dotEnv might be included in the common ionic project. 2) Multi entry point should be supported in a more intuitive way, so i ca add it to my config instead of cloning the whole webpack from appscript and modify.

/*
 * 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;

/**
 * custom start
 */
var dotenvConfig = require('dotenv').config({ path: './config/env/' + process.env.IONIC_ENV + ".env" });
var _ = require('lodash');

function getExtraPlugins() {
  let dotEnvPlugin = new webpack.DefinePlugin({
    'process.env': _(process.env)
      .pick(_.keys(dotenvConfig.parsed))
      .mapValues((v) => (JSON.stringify(v)))
      .value()
  });
  return [
    dotEnvPlugin,
    new webpack.optimize.CommonsChunkPlugin({ name: "rvt", filename: "rvt.js", chunks:["rvt"] }),
    new webpack.optimize.CommonsChunkPlugin({ name: "match", filename: "match.js", chunks:["match"] })
  ]
}
/**
 * custom end
 */

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: {
    main: process.env.IONIC_APP_ENTRY_POINT,
    rvt: __dirname + '/../src/lib/ms-rvt/db',
    match: __dirname + '/../src/lib/ms-match'
  },
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
    //custom
    libraryTarget: 'var',
    library: '[name]'
  },
  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: [
    ...getExtraPlugins(),
    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: {
    main: process.env.IONIC_APP_ENTRY_POINT,
    rvt: __dirname + '/../src/lib/ms-rvt/db',
    match: __dirname + '/../src/lib/ms-match'
  },
  output: {
    path: '{{BUILD}}',
    publicPath: 'build/',
    filename: '[name].js',
    devtoolModuleFilenameTemplate: ionicWebpackFactory.getSourceMapperFunction(),
    //custom
    libraryTarget: 'var',
    library: '[name]'
  },
  devtool: process.env.IONIC_SOURCE_MAP_TYPE,

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

  module: {
    loaders: getProdLoaders()
  },

  plugins: [
    ...getExtraPlugins(),
    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
}