diff --git a/index.js b/index.js index f9a92f11..e76ce2cb 100644 --- a/index.js +++ b/index.js @@ -66,6 +66,19 @@ exports.getEntryPathRegExp = (appFullPath, entryModule) => { const escapedPath = entryModuleFullPath.replace(/\\/g, "\\\\"); return new RegExp(escapedPath); } + +exports.getSourceMapFilename = (hiddenSourceMap, appFolderPath, outputPath) => { + const appFolderRelativePath = path.join(path.relative(outputPath, appFolderPath)); + let sourceMapFilename = "[file].map"; + if (typeof hiddenSourceMap === "string") { + sourceMapFilename = path.join(appFolderRelativePath, hiddenSourceMap, "[file].map"); + } else if (typeof hiddenSourceMap === "boolean" && !!hiddenSourceMap) { + sourceMapFilename = path.join(appFolderRelativePath, "sourceMap", "[file].map"); + } + + return sourceMapFilename; +} + /** * Converts an array of strings externals to an array of regular expressions. * Input is an array of string, which we need to convert to regular expressions, so all imports for this module will be treated as externals. diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index 1701216b..a18491d8 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -47,6 +47,7 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, unitTesting, // --env.unitTesting } = env; @@ -96,6 +97,8 @@ module.exports = env => { additionalLazyModuleResources: additionalLazyModuleResources }); + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -112,6 +115,7 @@ module.exports = env => { output: { pathinfo: false, path: dist, + sourceMapFilename, libraryTarget: "commonjs2", filename: "[name].js", globalObject: "global", @@ -142,7 +146,7 @@ module.exports = env => { "fs": "empty", "__dirname": false, }, - devtool: sourceMap ? "inline-source-map" : "none", + devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), optimization: { runtimeChunk: "single", splitChunks: { @@ -164,7 +168,7 @@ module.exports = env => { new UglifyJsPlugin({ parallel: true, cache: true, - sourceMap: !!sourceMap, + sourceMap: !!sourceMap || !!hiddenSourceMap, uglifyOptions: { output: { comments: false, diff --git a/templates/webpack.config.spec.ts b/templates/webpack.config.spec.ts index 35db7d4b..da7c246c 100644 --- a/templates/webpack.config.spec.ts +++ b/templates/webpack.config.spec.ts @@ -1,5 +1,7 @@ import * as proxyquire from 'proxyquire'; import * as nsWebpackIndex from '../index'; +import { join } from 'path'; +import { skipPartiallyEmittedExpressions } from 'typescript'; // With noCallThru enabled, `proxyquire` will not fall back to requiring the real module to populate properties that are not mocked. // This allows us to mock packages that are not available in node_modules. // In case you want to enable fallback for a specific object, just add `'@noCallThru': false`. @@ -14,6 +16,13 @@ class AngularCompilerStub { } }; +let uglifyJsOptions: any; +class UglifyJsStub { + constructor(options) { + uglifyJsOptions = options; + } +}; + const nativeScriptDevWebpack = { GenerateBundleStarterPlugin: EmptyClass, WatchStateLoggerPlugin: EmptyClass, @@ -22,7 +31,8 @@ const nativeScriptDevWebpack = { getEntryModule: () => 'EntryModule', getResolver: () => null, getEntryPathRegExp: () => null, - getConvertedExternals: nsWebpackIndex.getConvertedExternals + getConvertedExternals: nsWebpackIndex.getConvertedExternals, + getSourceMapFilename: nsWebpackIndex.getSourceMapFilename }; const emptyObject = {}; @@ -39,29 +49,33 @@ const webpackConfigAngular = proxyquire('./webpack.angular', { 'nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin': { getAngularCompilerPlugin: () => { return AngularCompilerStub; } }, '@ngtools/webpack': { AngularCompilerPlugin: AngularCompilerStub - } + }, + 'uglifyjs-webpack-plugin': UglifyJsStub }); const webpackConfigTypeScript = proxyquire('./webpack.typescript', { 'nativescript-dev-webpack': nativeScriptDevWebpack, 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'uglifyjs-webpack-plugin': UglifyJsStub }); const webpackConfigJavaScript = proxyquire('./webpack.javascript', { 'nativescript-dev-webpack': nativeScriptDevWebpack, 'nativescript-dev-webpack/nativescript-target': emptyObject, + 'uglifyjs-webpack-plugin': UglifyJsStub }); const webpackConfigVue = proxyquire('./webpack.vue', { 'nativescript-dev-webpack': nativeScriptDevWebpack, 'nativescript-dev-webpack/nativescript-target': emptyObject, 'vue-loader/lib/plugin': EmptyClass, - 'nativescript-vue-template-compiler': emptyObject + 'nativescript-vue-template-compiler': emptyObject, + 'uglifyjs-webpack-plugin': UglifyJsStub }); describe('webpack.config.js', () => { - const getInput = (options: { platform: string, aot?: boolean, hmr?: boolean, externals?: string[] }) => { - const input: any = { aot: options.aot, hmr: options.hmr, externals: options.externals }; + const getInput = (options: { platform: string, aot?: boolean, hmr?: boolean, externals?: string[], sourceMap?: boolean, hiddenSourceMap?: boolean | string }) => { + const input: any = Object.assign({}, options);; input[options.platform] = true; return input; }; @@ -73,182 +87,252 @@ describe('webpack.config.js', () => { { type: 'vue', webpackConfig: webpackConfigVue } ].forEach(element => { const { type, webpackConfig } = element; + [ + 'android', + 'ios' + ].forEach(platform => { + describe(`verify externals for webpack.${type}.js (${platform})`, () => { + afterEach(() => { + nativeScriptDevWebpack.getConvertedExternals = nsWebpackIndex.getConvertedExternals; + }); + + it('returns empty array when externals are not passed', () => { + const input = getInput({ platform }); + const config = webpackConfig(input); + expect(config.externals).toEqual([]); + }); - describe(`verify externals for webpack.${type}.js`, () => { - [ - 'android', - 'ios' - ].forEach(platform => { - describe(`for ${platform}`, () => { - afterEach(() => { - nativeScriptDevWebpack.getConvertedExternals = nsWebpackIndex.getConvertedExternals; + it('calls getConvertedExternals to convert externals', () => { + let isCalled = false; + nativeScriptDevWebpack.getConvertedExternals = () => { + isCalled = true; + return []; + }; + + const input = getInput({ platform, externals: ['nativescript-vue'] }); + webpackConfig(input); + expect(isCalled).toBe(true, 'Webpack.config.js must use the getConvertedExternals method'); + }); + + [ + { + input: ['nativescript-vue'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/] + }, + { + input: ['nativescript-vue', 'nativescript-angular'], + expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] + }, + ].forEach(testCase => { + const input = getInput({ platform, externals: testCase.input }); + + it(`are correct regular expressions, for input ${testCase.input}`, () => { + const config = webpackConfig(input); + expect(config.externals).toEqual(testCase.expectedOutput); }); + }); + }); + - it('returns empty array when externals are not passed', () => { + if (type === 'angular') { + describe(`angular transformers for webpack.${type}.js (${platform})`, () => { + + beforeEach(() => { + angularCompilerOptions = null; + }); + + it("should be empty by default", () => { const input = getInput({ platform }); - const config = webpackConfig(input); - expect(config.externals).toEqual([]); + + webpackConfig(input); + + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(0); }); - it('calls getConvertedExternals to convert externals', () => { - let isCalled = false; - nativeScriptDevWebpack.getConvertedExternals = () => { - isCalled = true; - return []; - }; + it("should contain the AOT transformer when the AOT flag is passed", () => { + const input = getInput({ platform, aot: true }); - const input = getInput({ platform, externals: ['nativescript-vue'] }); webpackConfig(input); - expect(isCalled).toBe(true, 'Webpack.config.js must use the getConvertedExternals method'); + + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(1); + expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); }); - [ - { - input: ['nativescript-vue'], - expectedOutput: [/^nativescript-vue((\/.*)|$)/] - }, - { - input: ['nativescript-vue', 'nativescript-angular'], - expectedOutput: [/^nativescript-vue((\/.*)|$)/, /^nativescript-angular((\/.*)|$)/] - }, - ].forEach(testCase => { - const input = getInput({ platform, externals: testCase.input }); - - it(`are correct regular expressions, for input ${testCase.input}`, () => { - const config = webpackConfig(input); - expect(config.externals).toEqual(testCase.expectedOutput); - }); + it("should contain the HMR transformer when the HMR flag is passed", () => { + const input = getInput({ platform, hmr: true }); + + webpackConfig(input); + + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(1); + expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeHmrTransformerFlag); }); - }); - }); - }); - }); - [ - 'android', - 'ios' - ].forEach(platform => { - describe(`angular transformers (${platform})`, () => { + it("should contain the Lazy transformer when the @angular/core is an external module", () => { + const input = getInput({ platform, externals: ["@angular/core"] }); - beforeEach(() => { - angularCompilerOptions = null; - }); + webpackConfig(input); - it("should be empty by default", () => { - const input = getInput({ platform }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(1); + expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeLazyTransformerFlag); + }); - webpackConfigAngular(input); + it("should contain the AOT + HMR transformers when the AOT and HMR flags are passed", () => { + const input = getInput({ platform, aot: true, hmr: true }); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(0); - }); + webpackConfig(input); + + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(2); + expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); + expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); + }); - it("should contain the AOT transformer when the AOT flag is passed", () => { - const input = getInput({ platform, aot: true }); + it("should set the AOT transformer before the HMR one when the AOT and HMR flags are passed", () => { + const input = getInput({ platform, aot: true, hmr: true }); - webpackConfigAngular(input); + webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(1); - expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); - }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(2); + expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); + expect(angularCompilerOptions.platformTransformers[1]).toEqual(FakeHmrTransformerFlag); + }); - it("should contain the HMR transformer when the HMR flag is passed", () => { - const input = getInput({ platform, hmr: true }); + it("should contain the AOT + Lazy transformers when the AOT flag is passed and @angular/core is an external module", () => { + const input = getInput({ platform, aot: true, externals: ["@angular/core"] }); - webpackConfigAngular(input); + webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(1); - expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeHmrTransformerFlag); - }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(2); + expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); + expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); + }); - it("should contain the Lazy transformer when the @angular/core is an external module", () => { - const input = getInput({ platform, externals: ["@angular/core"] }); + it("should contain the HMR + Lazy transformers when the HMR flag is passed and @angular/core is an external module", () => { + const input = getInput({ platform, hmr: true, externals: ["@angular/core"] }); - webpackConfigAngular(input); + webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(1); - expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeLazyTransformerFlag); - }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(2); + expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); + expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); + }); - it("should contain the AOT + HMR transformers when the AOT and HMR flags are passed", () => { - const input = getInput({ platform, aot: true, hmr: true }); + it("should contain the AOT + HMR + Lazy transformers when the AOT and HMR flags are passed and @angular/core is an external module", () => { + const input = getInput({ platform, aot: true, hmr: true, externals: ["@angular/core"] }); - webpackConfigAngular(input); + webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(2); - expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); - expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); - }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(3); + expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); + expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); + expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); + }); - it("should set the AOT transformer before the HMR one when the AOT and HMR flags are passed", () => { - const input = getInput({ platform, aot: true, hmr: true }); + it("should contain the AOT + HMR + Lazy transformers in the proper order when the AOT and HMR flags are passed and @angular/core is an external module", () => { + const input = getInput({ platform, aot: true, hmr: true, externals: ["@angular/core"] }); - webpackConfigAngular(input); + webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(2); - expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); - expect(angularCompilerOptions.platformTransformers[1]).toEqual(FakeHmrTransformerFlag); - }); + expect(angularCompilerOptions).toBeDefined(); + expect(angularCompilerOptions.platformTransformers).toBeDefined(); + expect(angularCompilerOptions.platformTransformers.length).toEqual(3); + expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); + expect(angularCompilerOptions.platformTransformers[1]).toEqual(FakeHmrTransformerFlag); + expect(angularCompilerOptions.platformTransformers[2]).toEqual(FakeLazyTransformerFlag); + }); + }); + } - it("should contain the AOT + Lazy transformers when the AOT flag is passed and @angular/core is an external module", () => { - const input = getInput({ platform, aot: true, externals: ["@angular/core"] }); + describe(`source map for webpack.${type}.js (${platform})`, () => { - webpackConfigAngular(input); + beforeEach(() => { + uglifyJsOptions = null; + }); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(2); - expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); - expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); - }); + it("should not set source maps without the flag", () => { + const input = getInput({ platform, sourceMap: false }); - it("should contain the HMR + Lazy transformers when the HMR flag is passed and @angular/core is an external module", () => { - const input = getInput({ platform, hmr: true, externals: ["@angular/core"] }); + const config = webpackConfig(input); - webpackConfigAngular(input); + expect(config.devtool).toEqual("none"); + expect(uglifyJsOptions.sourceMap).toBeFalsy(); + expect(config.output.sourceMapFilename).toEqual("[file].map"); + }); + + it("should set inline-source-map devtool", () => { + const input = getInput({ platform, sourceMap: true }); + + const config = webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(2); - expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); - expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); + expect(config.devtool).toEqual("inline-source-map"); + expect(uglifyJsOptions.sourceMap).toBeTruthy(); + expect(config.output.sourceMapFilename).toEqual("[file].map"); + }); }); - it("should contain the AOT + HMR + Lazy transformers when the AOT and HMR flags are passed and @angular/core is an external module", () => { - const input = getInput({ platform, aot: true, hmr: true, externals: ["@angular/core"] }); + describe(`hidden source map for webpack.${type}.js (${platform})`, () => { - webpackConfigAngular(input); + beforeEach(() => { + uglifyJsOptions = null; + }); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(3); - expect(angularCompilerOptions.platformTransformers).toContain(FakeAotTransformerFlag); - expect(angularCompilerOptions.platformTransformers).toContain(FakeHmrTransformerFlag); - expect(angularCompilerOptions.platformTransformers).toContain(FakeLazyTransformerFlag); - }); + it("should not set source maps without the flag", () => { + const input = getInput({ platform, hiddenSourceMap: false }); + + const config = webpackConfig(input); + + expect(config.devtool).toEqual("none"); + expect(uglifyJsOptions.sourceMap).toBeFalsy(); + expect(config.output.sourceMapFilename).toEqual("[file].map"); + }); - it("should contain the AOT + HMR + Lazy transformers in the proper order when the AOT and HMR flags are passed and @angular/core is an external module", () => { - const input = getInput({ platform, aot: true, hmr: true, externals: ["@angular/core"] }); + it("should set hidden-source-map devtool and the default sourceMap folder", () => { + const input = getInput({ platform, hiddenSourceMap: true }); - webpackConfigAngular(input); + const config = webpackConfig(input); - expect(angularCompilerOptions).toBeDefined(); - expect(angularCompilerOptions.platformTransformers).toBeDefined(); - expect(angularCompilerOptions.platformTransformers.length).toEqual(3); - expect(angularCompilerOptions.platformTransformers[0]).toEqual(FakeAotTransformerFlag); - expect(angularCompilerOptions.platformTransformers[1]).toEqual(FakeHmrTransformerFlag); - expect(angularCompilerOptions.platformTransformers[2]).toEqual(FakeLazyTransformerFlag); + expect(config.devtool).toEqual("hidden-source-map"); + expect(uglifyJsOptions.sourceMap).toBeTruthy(); + expect(config.output.sourceMapFilename).toEqual(join("..", "sourceMap", "[file].map")); + }); + + it("should override the sourceMap property and the default sourceMap folder", () => { + const input = getInput({ platform, sourceMap: true, hiddenSourceMap: true }); + + const config = webpackConfig(input); + + expect(config.devtool).toEqual("hidden-source-map"); + expect(uglifyJsOptions.sourceMap).toBeTruthy(); + expect(config.output.sourceMapFilename).toEqual(join("..", "sourceMap", "[file].map")); + }); + + it("should set hidden-source-map devtool and override the sourceMapFilename", () => { + const newSourceMapFolder = "myCoolSourceMapFolder"; + const input = getInput({ platform, sourceMap: true, hiddenSourceMap: newSourceMapFolder }); + + const config = webpackConfig(input); + + expect(config.devtool).toEqual("hidden-source-map"); + expect(uglifyJsOptions.sourceMap).toBeTruthy(); + expect(config.output.sourceMapFilename).toEqual(join("..", newSourceMapFolder, "[file].map")); + }); }); }); }); diff --git a/templates/webpack.javascript.js b/templates/webpack.javascript.js index 00bbc37f..5f5691df 100644 --- a/templates/webpack.javascript.js +++ b/templates/webpack.javascript.js @@ -41,6 +41,7 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, unitTesting, // --env.unitTesting } = env; @@ -56,6 +57,8 @@ module.exports = env => { entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules.js"; }; + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -72,6 +75,7 @@ module.exports = env => { output: { pathinfo: false, path: dist, + sourceMapFilename, libraryTarget: "commonjs2", filename: "[name].js", globalObject: "global", @@ -102,7 +106,7 @@ module.exports = env => { "fs": "empty", "__dirname": false, }, - devtool: sourceMap ? "inline-source-map" : "none", + devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), optimization: { runtimeChunk: "single", splitChunks: { @@ -125,7 +129,7 @@ module.exports = env => { new UglifyJsPlugin({ parallel: true, cache: true, - sourceMap: !!sourceMap, + sourceMap: !!sourceMap || !!hiddenSourceMap, uglifyOptions: { output: { comments: false, diff --git a/templates/webpack.typescript.js b/templates/webpack.typescript.js index 2b12c3a3..ae521f8f 100644 --- a/templates/webpack.typescript.js +++ b/templates/webpack.typescript.js @@ -41,6 +41,7 @@ module.exports = env => { uglify, // --env.uglify report, // --env.report sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap hmr, // --env.hmr, unitTesting, // --env.unitTesting } = env; @@ -56,6 +57,8 @@ module.exports = env => { entries["tns_modules/tns-core-modules/inspector_modules"] = "inspector_modules.js"; }; + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const config = { mode: uglify ? "production" : "development", context: appFullPath, @@ -72,6 +75,7 @@ module.exports = env => { output: { pathinfo: false, path: dist, + sourceMapFilename, libraryTarget: "commonjs2", filename: "[name].js", globalObject: "global", @@ -104,7 +108,7 @@ module.exports = env => { "fs": "empty", "__dirname": false, }, - devtool: sourceMap ? "inline-source-map" : "none", + devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), optimization: { runtimeChunk: "single", splitChunks: { @@ -127,7 +131,7 @@ module.exports = env => { new UglifyJsPlugin({ parallel: true, cache: true, - sourceMap: !!sourceMap, + sourceMap: !!sourceMap || !!hiddenSourceMap, uglifyOptions: { output: { comments: false, diff --git a/templates/webpack.vue.js b/templates/webpack.vue.js index 1f3c36da..7f3ae42c 100644 --- a/templates/webpack.vue.js +++ b/templates/webpack.vue.js @@ -46,6 +46,7 @@ module.exports = env => { report, // --env.report hmr, // --env.hmr sourceMap, // --env.sourceMap + hiddenSourceMap, // --env.hiddenSourceMap unitTesting, // --env.unitTesting } = env; @@ -64,6 +65,8 @@ module.exports = env => { }; console.log(`Bundling application for entryPath ${entryPath}...`); + let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); + const config = { mode: mode, context: appFullPath, @@ -81,6 +84,7 @@ module.exports = env => { output: { pathinfo: false, path: dist, + sourceMapFilename, libraryTarget: "commonjs2", filename: "[name].js", globalObject: "global", @@ -115,7 +119,7 @@ module.exports = env => { "fs": "empty", "__dirname": false, }, - devtool: sourceMap ? "inline-source-map" : "none", + devtool: hiddenSourceMap ? "hidden-source-map" : (sourceMap ? "inline-source-map" : "none"), optimization: { runtimeChunk: "single", splitChunks: { @@ -138,7 +142,7 @@ module.exports = env => { new UglifyJsPlugin({ parallel: true, cache: true, - sourceMap: !!sourceMap, + sourceMap: !!sourceMap || !!hiddenSourceMap, uglifyOptions: { output: { comments: false,