1

We are having two Aurelia apps inside the same /src. One is the main app and the other is in the subfolder which uses some modules of the main app. Please see the file structure below to get an understanding.

enter image description here

This was working fine before when we were using the webpack 3. After we upgraded to webpack 4 and made the changes in the config, the build of the main app works as expected. But when we build the sub app, same main app bundles gets built to the output folder for sub app.

Please find below for the code on our webpack.config.ts file

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { ProvidePlugin } = require('webpack');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const TsConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { CheckerPlugin } = require('awesome-typescript-loader');

// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
  condition ? ensureArray(config) : ensureArray(negativeConfig);

// primary config:
const title = 'Aurelia Navigation Skeleton';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';

const cssRules = [
  { loader: 'css-loader' },
];

module.exports = ({ production, server, extractCss, coverage } = {}) => ({
  mode: production ? 'production' : 'development',
  resolve: {
    extensions: ['.ts', '.js'],
    modules: [srcDir, 'node_modules'],
    plugins: [new TsConfigPathsPlugin()]
  },
  entry: {
    app: ['./ie-polyfill', 'aurelia-bootstrapper'],
    vendor: ['bluebird'],
  },
  output: {
    path: outDir,
    publicPath: baseUrl,
    filename: '[name].bundle.js',
    sourceMapFilename: '[name].bundle.map',
    chunkFilename: '[name].chunk.js'
  },
  optimization: {
    minimize: production ? true : false,
  },
  devServer: {
    contentBase: outDir,
    // serve index.html for all 404 (required for push-state)
    historyApiFallback: true
  },
  devtool: production ? 'nosources-source-map' : 'cheap-module-eval-source-map',
  module: {
    rules: [
      // CSS required in JS/TS files should use the style-loader that auto-injects it into the website
      // only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
      {
        test: /\.css$/i,
        issuer: [{ not: [{ test: /\.html$/i }] }],
        use: extractCss ? ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: cssRules
        }) : ['style-loader', ...cssRules],
      },
      {
        test: /\.css$/i,
        issuer: [{ test: /\.html$/i }],
        // CSS required in templates cannot be extracted safely
        // because Aurelia would try to require it again in runtime
        use: cssRules
      },
      { test: /\.html$/i, loader: 'html-loader' },
      { test: /\.ts$/i, loader: 'awesome-typescript-loader', exclude: nodeModulesDir },
      { test: /\.json$/i, loader: 'json-loader' },
      // use Bluebird as the global Promise implementation:
      { test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' },
      // embed small images and fonts as Data Urls and larger ones as files:
      { test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
      { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
      { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
      // load these fonts normally, as files:
      { test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
      ...when(coverage, {
        test: /\.[jt]s$/i, loader: 'istanbul-instrumenter-loader',
        include: srcDir, exclude: [/\.{spec,test}\.[jt]s$/i],
        enforce: 'post', options: { esModules: true },
      })
    ]
  },
  plugins: [
    new AureliaPlugin(),

    new ProvidePlugin({
      'Promise': 'bluebird'
    }),

    new ModuleDependenciesPlugin({
      'aurelia-testing': ['./compile-spy', './view-spy'],
      'aurelia-orm': [
        './component/association-select',
        './component/paged',
        './component/view/bootstrap/association-select.html',
        './component/view/bootstrap/paged.html',
      ],
      "aurelia-syncfusion-bridge": [
        "./grid/grid",
        "./grid/column",
        "./common/template"
      ],
      "aurelia-authentication": [
        "./authFilterValueConverter"
      ]
    }),

    new CheckerPlugin(),

    new HtmlWebpackPlugin({
      template: 'index.ejs',
      minify: production ? {
        removeComments: true,
        collapseWhitespace: true,
        collapseInlineTagWhitespace: true,
        collapseBooleanAttributes: true,
        removeAttributeQuotes: true,
        minifyCSS: true,
        minifyJS: true,
        removeScriptTypeAttributes: true,
        removeStyleLinkTypeAttributes: true,
        ignoreCustomFragments: [/\${.*?}/g]
      } : undefined,
      metadata: {
        // available in index.ejs //
        title, server, baseUrl
      }
    }),

    ...when(extractCss, new ExtractTextPlugin({
      filename: production ? '[contenthash].css' : '[id].css',
      allChunks: true
    })),

    ...when(production, new CopyWebpackPlugin([
      { from: 'static/favicon.ico', to: 'favicon.ico' }
    ]))

   ]
  });

Here is the code of webpack.subapp.config.ts

const path = require('path');
const webpackConfig = require('./webpack.config');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
var originalConfig = webpackConfig({});

const outDir = path.resolve(__dirname, project.platform.output+'/associate');
const srcDir = path.resolve(__dirname, 'src');


module.exports = () => {
  let config = originalConfig;
  // output files without hashes
  config.resolve.modules.push(
    path.resolve(__dirname, 'src/associate')
  );
  //config.resolve.modules = [srcDir + '/associate', srcDir, 'node_modules'];
  config.output.path = outDir;
  config.output.filename = '[name].bundle.js';
  config.plugins.splice(config.plugins.indexOf(HtmlWebpackPlugin));
  config.plugins = [
    // first clean the output directory
    new CleanWebpackPlugin([config.output.path + '/associate']),
    ...config.plugins
  ];

  return config;
};

The problem is that the main.ts of the main app is the entry point and it was not working even when we tried multiple entry points.

When we removed the main.ts from the src folder, the build of sub-app worked perfectly and bundle created correctly.

So the problem is it's taking the main.ts of the main app. We tried excluding it in the config by following ways

congif.exclude = [srcDir + '/main.ts'];

and then

config.module.rules[3].exclude = [srcDir + '/main.ts'];

But none worked.

Please help find how to exclude the main.ts of /src in webpack.subapp.config.ts

AeJey
  • 1,447
  • 20
  • 40
  • There are several similar questions on Aurelia Discourse forum, this is an example https://discourse.aurelia.io/t/multiple-app-bundles-and-service-registration/309/23 Can you go have a look to see if it applies ? – bigopon Sep 14 '18 at 11:15

0 Answers0