Skip to content

Add possibility to use webpack with an alternative file system #9089

@nicojs

Description

@nicojs

Repro steps

Create a new project with ng new <project>. Cd in the directory and create a new file called "main.js" with the following content:

// main.js
const path = require('path');
const webpack = require('webpack');

const angularCliConfig = require('./.angular-cli');
const getAppFromConfig = require('@angular/cli/utilities/app-utils').getAppFromConfig;
const WebpackTestConfig = require('@angular/cli/models/webpack-test-config').WebpackTestConfig;

const appConfig = getAppFromConfig(undefined);

const testConfig = Object.assign({
  environment: 'dev',
  codeCoverage: false,
  sourcemaps: false,
  progress: true,
  preserveSymlinks: false,
});

const webpackConfig = new WebpackTestConfig(testConfig, appConfig).buildConfig();
delete webpackConfig.entry.styles;
webpackConfig.devtool = false;

const compiler = webpack(webpackConfig);
const fs = compiler.inputFileSystem;
const originalReadFile = fs.readFile;
fs.readFile = function (name, optionalArgs, callback) {
  if (name === path.resolve(__dirname, 'src', 'app', 'app.component.ts')) {
    if (!callback) {
      callback = optionalArgs;
    }
    callback(null, `alert('hello world!')`);
  } else {
    originalReadFile.apply(fs, [name, optionalArgs, callback]);
  }
}
compiler.run(() => {
  console.log('Done');
});

Run the "main.js" file.

Example project can be cloned here: https://github.com/nicojs/angular-cli-with-alternative-filesystem

Observed behavior

The original content from disk is bundled. The "main.bundle.js" file contains:

var AppComponent = (function () {
    function AppComponent() {
        this.title = 'app';
    }
   // ...
}());

Desired behavior

I would expect the 'main.bundle.js' to contain the alert('hello world') content as read from the input file system (or a compiler compiler error in this case...).

The use case here is that we want to use the angular webpack compiler with an in-memory filesystem. This is used by Stryker (https://stryker-mutator.github.io) to transpile input files in-memory.

Mention any other details that might be useful (optional)

We've looked into the problem and believe it lies within the 'WebpackCompilerHost.ts' file here:

this._delegate = ts.createCompilerHost(this._options, this._setParentNodes);

It creates a typescript compiler host which in turn uses the actual file system rather than passing through the webpack input file system.

Versions

ng version

    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/

Angular CLI: 1.6.3
Node: 8.2.1
OS: win32 x64
Angular: 5.1.2
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.6.3
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.3
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.4.2
webpack: 3.10.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions