systemjs / builder

SystemJS build tool
MIT License
465 stars 122 forks source link

Allow browserBaseURL prefix to apply to `__moduleName` and other name outputs #737

Open vdolbnya opened 7 years ago

vdolbnya commented 7 years ago

I have an Angular2 application which is started by following:

   <base href="/content/app/">

    <script src="bundle.js"></script>

I'm creating bundle using following script Bundle.js is creating by following script:

var SystemBuilder = require('systemjs-builder');
var builder = new SystemBuilder();

builder.loadConfig('./systemjs.config.js')
  .then(function(){
      var outputFile = './bundle.js';
      return builder.buildStatic('./boot', outputFile, {
          minify: true,
          mangle: true,
          rollup: true,
            encodeNames :false
      });
  })
  .then(function(){
      console.log('bundle built successfully!');
  });

My systemjs.config.js is:

(function (global) {

    // map tells the System loader where to look for things
    var map = {
        "moment": 'node_modules/moment',
        "underscore": "node_modules/underscore/underscore.js",
        "rxjs": "node_modules/rxjs",
        "@angular": "node_modules/@angular",
        "symbol-observable": "node_modules/symbol-observable",
        "ng2-ckeditor": "node_modules/ng2-ckeditor",
        "ng2-datetime": "node_modules/ng2-datetime",
        "ng2-bootstrap": "node_modules/ng2-bootstrap",
    };

    // packages tells the System loader how to load when no filename and/or no extension
    var packages = {
        components: {
            defaultExtension: 'js'
        },
        resources: {
            defaultExtension: 'js'
        },
        core: {
            defaultExtension: 'js'
        },
        services: {
            defaultExtension: 'js'
        },
        'rxjs': { main: 'bundles/Rx.js', defaultExtension: 'js' },
        "symbol-observable": { main: "index.js" },
        "ng2-ckeditor": { main: 'lib/CKEditor.js', defaultExtension: 'js' },
        "ng2-datetime": { main: "ng2-datetime.js", defaultExtension: 'js' },
        "moment": { main: "moment.js", defaultExtension: 'js' }
    };

    var ngPackageNames = [
        'common',
        'compiler',
        'core',
        'http',
        'forms',
        'platform-browser',
        'platform-browser-dynamic',
        'router',
        'testing',
        'upgrade',
    ];

    // Individual files (~300 requests):
    function packIndex(pkgName) {
        packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
    }

    // Bundled (~40 requests):
    function packUmd(pkgName) {
        map['@angular/' + pkgName] = 'node_modules/@angular/' + pkgName + '/bundles/' + pkgName + '.umd.js';
    }

    // Most environments should use UMD; some (Karma) need the individual index files
    var setPackageConfig = packUmd;

    // Add package entries for angular packages
    ngPackageNames.forEach(setPackageConfig);

    // No umd for router yet
    packages['@angular/upgrade'] = { main: 'index.js', defaultExtension: 'js' };

    var config = {
        defaultJSExtensions: true,
        map: map,
        packages: packages
    };
    System.config(config);
})(this);`

and I'm trying to resolve relative templateUrl and styleUrl paths in components using following approach:

declare global {
    var __moduleName: string
}

@Component({
    moduleId: __moduleName,
    providers: [UserApiService, SecurityBatchApiService],
    templateUrl: `./user.list.html`
})

Without bundling all works fine and and moduleName in case of this component is equals to http://localhost:9000/content/app/security-ui/users/components/user.list.js But in case of bundling moduleName is different: security-ui/users/components/user.list.js as you see http://localhost:9000/content/app/ is missing but in fact system will work with __moduleName like content/app/security-ui/users/components/user.list.js and difference is content/app which is in fact my base href.

So question is: how I can configure system.config.js or builder.loadConfig to to prefix __moduleName with my base href or is there is another way to overcome this problem?

guybedford commented 7 years ago

I've renamed the issue - we can certainly support something like:

return builder.buildStatic('./boot', outputFile, {
  publicBaseURL: '/content/app/'
});

That then adds this prefix to __moduleName, module.id in CommonJS, etc.

Any PRs welcome here.

guybedford commented 7 years ago

Perhaps browserBaseURL makes more sense as the name.