UNPKG

@angular-devkit/build-angular

Version:
114 lines (113 loc) 4.85 kB
"use strict"; /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = require("path"); const rollup_1 = require("rollup"); function splitRequest(request) { const inx = request.lastIndexOf('!'); if (inx === -1) { return { loaders: '', resource: request, }; } else { return { loaders: request.slice(0, inx + 1), resource: request.slice(inx + 1), }; } } // Load resolve paths using Webpack. function webpackResolutionPlugin(loaderContext, entryId, entryIdCodeAndMap) { return { name: 'webpack-resolution-plugin', resolveId: (id, importerId) => { if (id === entryId) { return entryId; } else { return new Promise((resolve, reject) => { // split apart resource paths because Webpack's this.resolve() can't handle `loader!` // prefixes const parts = splitRequest(id); const importerParts = splitRequest(importerId); // resolve the full path of the imported file with Webpack's module loader // this will figure out node_modules imports, Webpack aliases, etc. loaderContext.resolve(path_1.dirname(importerParts.resource), parts.resource, (err, fullPath) => err ? reject(err) : resolve(parts.loaders + fullPath)); }); } }, load: (id) => { if (id === entryId) { return entryIdCodeAndMap; } return new Promise((resolve, reject) => { // load the module with Webpack // this will apply all relevant loaders, etc. loaderContext.loadModule(id, (err, source, map) => err ? reject(err) : resolve({ code: source, map: map })); }); }, }; } function webpackRollupLoader(source, sourceMap) { // Note: this loader isn't cacheable because it will add the lazy chunks to the // virtual file system on completion. const callback = this.async(); if (!callback) { throw new Error('Async loader support is required.'); } const options = this.query || {}; const entryId = this.resourcePath; const sourcemap = this.sourceMap; // Get the VirtualFileSystemDecorator that AngularCompilerPlugin added so we can write to it. // Since we use webpackRollupLoader as a post loader, this should be there. // TODO: we should be able to do this in a more elegant way by again decorating webpacks // input file system inside a custom WebpackRollupPlugin, modelled after AngularCompilerPlugin. const vfs = this._compiler.inputFileSystem; const virtualWrite = (path, data) => vfs.getWebpackCompilerHost().writeFile(path, data, false); // Bundle with Rollup const rollupOptions = { ...options, input: entryId, plugins: [ ...(options.plugins || []), webpackResolutionPlugin(this, entryId, { code: source, map: sourceMap }), ], }; rollup_1.rollup(rollupOptions) .then(build => build.generate({ format: 'es', sourcemap })) .then((result) => { const [mainChunk, ...otherChunksOrAssets] = result.output; // Write other chunks and assets to the virtual file system so that webpack can load them. const resultDir = path_1.dirname(entryId); otherChunksOrAssets.forEach(chunkOrAsset => { const { fileName, type } = chunkOrAsset; if (type == 'chunk') { const { code, map } = chunkOrAsset; virtualWrite(path_1.join(resultDir, fileName), code); if (map) { // Also write the map if there's one. // Probably need scriptsSourceMap set on CLI to load it. virtualWrite(path_1.join(resultDir, `${fileName}.map`), map.toString()); } } else if (type == 'asset') { const { source } = chunkOrAsset; // Source might be a Buffer. Just assuming it's a string for now. virtualWrite(path_1.join(resultDir, fileName), source); } }); // Always return the main chunk from webpackRollupLoader. // Cast to any here is needed because of a typings incompatibility between source-map versions. // tslint:disable-next-line:no-any callback(null, mainChunk.code, mainChunk.map); }, (err) => callback(err)); } exports.default = webpackRollupLoader;