Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

Commit e4bc3c5

Browse files
Merge pull request #1103 from NativeScript/tachev/fix-angular-scoped-packages
fix: avoid duplicate modules from tns-core-modules and @nativescript/core
2 parents 9358e83 + 2fe4928 commit e4bc3c5

File tree

4 files changed

+84
-19
lines changed

4 files changed

+84
-19
lines changed

Diff for: demo/AngularApp/webpack.config.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { nsReplaceBootstrap } = require("nativescript-dev-webpack/transformers/ns
77
const { nsReplaceLazyLoader } = require("nativescript-dev-webpack/transformers/ns-replace-lazy-loader");
88
const { nsSupportHmrNg } = require("nativescript-dev-webpack/transformers/ns-support-hmr-ng");
99
const { getMainModulePath } = require("nativescript-dev-webpack/utils/ast-utils");
10-
const { getNoEmitOnErrorFromTSConfig } = require("nativescript-dev-webpack/utils/tsconfig-utils");
10+
const { getNoEmitOnErrorFromTSConfig, getCompilerOptionsFromTSConfig } = require("nativescript-dev-webpack/utils/tsconfig-utils");
1111
const CleanWebpackPlugin = require("clean-webpack-plugin");
1212
const CopyWebpackPlugin = require("copy-webpack-plugin");
1313
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
@@ -61,19 +61,28 @@ module.exports = env => {
6161
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
6262
const externals = nsWebpack.getConvertedExternals(env.externals);
6363
const appFullPath = resolve(projectRoot, appPath);
64+
const tsConfigName = "tsconfig.tns.json";
65+
const tsConfigPath = join(__dirname, tsConfigName);
6466
const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot });
67+
const hasRootLevelScopedAngular = nsWebpack.hasRootLevelScopedAngular({ projectDir: projectRoot });
6568
let coreModulesPackageName = "tns-core-modules";
6669
const alias = {
6770
'~': appFullPath
6871
};
6972

73+
const compilerOptions = getCompilerOptionsFromTSConfig(tsConfigPath);
7074
if (hasRootLevelScopedModules) {
7175
coreModulesPackageName = "@nativescript/core";
7276
alias["tns-core-modules"] = coreModulesPackageName;
77+
nsWebpack.processTsPathsForScopedModules({ compilerOptions });
78+
}
79+
80+
if (hasRootLevelScopedAngular) {
7381
alias["nativescript-angular"] = "@nativescript/angular";
82+
nsWebpack.processTsPathsForScopedAngular({ compilerOptions });
7483
}
84+
7585
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
76-
const tsConfigName = "tsconfig.tns.json";
7786
const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
7887
const entryPath = `.${sep}${entryModule}`;
7988
const entries = { bundle: entryPath, application: "./application.android" };
@@ -110,10 +119,11 @@ module.exports = env => {
110119
hostReplacementPaths: nsWebpack.getResolver([platform, "tns"]),
111120
platformTransformers: ngCompilerTransformers.map(t => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot)),
112121
mainPath: join(appFullPath, entryModule),
113-
tsConfigPath: join(__dirname, tsConfigName),
122+
tsConfigPath,
114123
skipCodeGeneration: !aot,
115124
sourceMap: !!isAnySourceMapEnabled,
116-
additionalLazyModuleResources: additionalLazyModuleResources
125+
additionalLazyModuleResources: additionalLazyModuleResources,
126+
compilerOptions: { paths: compilerOptions.paths }
117127
});
118128

119129
let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);

Diff for: index.js

+49-9
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,28 @@ const {
1010
Object.assign(exports, require("./plugins"));
1111
Object.assign(exports, require("./host/resolver"));
1212

13+
exports.processTsPathsForScopedModules = function ({ compilerOptions }) {
14+
return replacePathInCompilerOptions({
15+
compilerOptions,
16+
targetPath: "tns-core-modules",
17+
replacementPath: "@nativescript/core"
18+
});
19+
}
20+
21+
exports.processTsPathsForScopedAngular = function ({ compilerOptions }) {
22+
return replacePathInCompilerOptions({
23+
compilerOptions,
24+
targetPath: "nativescript-angular",
25+
replacementPath: "@nativescript/angular"
26+
});
27+
}
28+
1329
exports.hasRootLevelScopedModules = function ({ projectDir }) {
14-
let hasRootLevelScopedModules;
15-
try {
16-
const scopedModulesPackageName = '@nativescript/core';
17-
require.resolve(scopedModulesPackageName, { paths: [projectDir] });
18-
hasRootLevelScopedModules = true;
19-
} catch (e) {
20-
hasRootLevelScopedModules = false;
21-
}
30+
return hasRootLevelPackage({ projectDir, packageName: "@nativescript/core" });
31+
}
2232

23-
return hasRootLevelScopedModules;
33+
exports.hasRootLevelScopedAngular = function ({ projectDir }) {
34+
return hasRootLevelPackage({ projectDir, packageName: "@nativescript/angular" });
2435
}
2536

2637
exports.getAotEntryModule = function (appDirectory) {
@@ -176,3 +187,32 @@ function verifyEntryModuleDirectory(appDirectory) {
176187
throw new Error(`The specified path to app directory ${appDirectory} does not exist. Unable to find entry module.`);
177188
}
178189
}
190+
191+
192+
function hasRootLevelPackage({ projectDir, packageName }) {
193+
let hasRootLevelPackage;
194+
try {
195+
require.resolve(packageName, { paths: [projectDir] });
196+
hasRootLevelPackage = true;
197+
} catch (e) {
198+
hasRootLevelPackage = false;
199+
}
200+
201+
return hasRootLevelPackage;
202+
}
203+
204+
function replacePathInCompilerOptions({ compilerOptions, targetPath, replacementPath }) {
205+
const paths = (compilerOptions && compilerOptions.paths) || {};
206+
for (const key in paths) {
207+
if (paths.hasOwnProperty(key)) {
208+
const pathsForPattern = paths[key];
209+
if (Array.isArray(pathsForPattern)) {
210+
for (let i = 0; i < pathsForPattern.length; ++i) {
211+
if (typeof pathsForPattern[i] === "string") {
212+
pathsForPattern[i] = pathsForPattern[i].replace(targetPath, replacementPath);
213+
}
214+
}
215+
}
216+
}
217+
}
218+
}

Diff for: templates/webpack.angular.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { nsReplaceBootstrap } = require("nativescript-dev-webpack/transformers/ns
77
const { nsReplaceLazyLoader } = require("nativescript-dev-webpack/transformers/ns-replace-lazy-loader");
88
const { nsSupportHmrNg } = require("nativescript-dev-webpack/transformers/ns-support-hmr-ng");
99
const { getMainModulePath } = require("nativescript-dev-webpack/utils/ast-utils");
10-
const { getNoEmitOnErrorFromTSConfig } = require("nativescript-dev-webpack/utils/tsconfig-utils");
10+
const { getNoEmitOnErrorFromTSConfig, getCompilerOptionsFromTSConfig } = require("nativescript-dev-webpack/utils/tsconfig-utils");
1111
const CleanWebpackPlugin = require("clean-webpack-plugin");
1212
const CopyWebpackPlugin = require("copy-webpack-plugin");
1313
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
@@ -60,19 +60,28 @@ module.exports = env => {
6060
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
6161
const externals = nsWebpack.getConvertedExternals(env.externals);
6262
const appFullPath = resolve(projectRoot, appPath);
63+
const tsConfigName = "tsconfig.tns.json";
64+
const tsConfigPath = join(__dirname, tsConfigName);
6365
const hasRootLevelScopedModules = nsWebpack.hasRootLevelScopedModules({ projectDir: projectRoot });
66+
const hasRootLevelScopedAngular = nsWebpack.hasRootLevelScopedAngular({ projectDir: projectRoot });
6467
let coreModulesPackageName = "tns-core-modules";
6568
const alias = {
6669
'~': appFullPath
6770
};
6871

72+
const compilerOptions = getCompilerOptionsFromTSConfig(tsConfigPath);
6973
if (hasRootLevelScopedModules) {
7074
coreModulesPackageName = "@nativescript/core";
7175
alias["tns-core-modules"] = coreModulesPackageName;
76+
nsWebpack.processTsPathsForScopedModules({ compilerOptions });
77+
}
78+
79+
if (hasRootLevelScopedAngular) {
7280
alias["nativescript-angular"] = "@nativescript/angular";
81+
nsWebpack.processTsPathsForScopedAngular({ compilerOptions });
7382
}
83+
7484
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
75-
const tsConfigName = "tsconfig.tns.json";
7685
const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
7786
const entryPath = `.${sep}${entryModule}`;
7887
const entries = { bundle: entryPath };
@@ -109,10 +118,11 @@ module.exports = env => {
109118
hostReplacementPaths: nsWebpack.getResolver([platform, "tns"]),
110119
platformTransformers: ngCompilerTransformers.map(t => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot)),
111120
mainPath: join(appFullPath, entryModule),
112-
tsConfigPath: join(__dirname, tsConfigName),
121+
tsConfigPath,
113122
skipCodeGeneration: !aot,
114123
sourceMap: !!isAnySourceMapEnabled,
115-
additionalLazyModuleResources: additionalLazyModuleResources
124+
additionalLazyModuleResources: additionalLazyModuleResources,
125+
compilerOptions: { paths: compilerOptions.paths }
116126
});
117127

118128
let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);

Diff for: templates/webpack.config.spec.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const nativeScriptDevWebpack = {
3030
getAppPath: () => 'app',
3131
getEntryModule: () => 'EntryModule',
3232
hasRootLevelScopedModules: () => false,
33+
hasRootLevelScopedAngular: () => false,
34+
processTsPathsForScopedModules: () => false,
35+
processTsPathsForScopedAngular: () => false,
3336
getResolver: () => null,
3437
getConvertedExternals: nsWebpackIndex.getConvertedExternals,
3538
getSourceMapFilename: nsWebpackIndex.getSourceMapFilename,
@@ -48,7 +51,7 @@ const webpackConfigAngular = proxyquire('./webpack.angular', {
4851
'nativescript-dev-webpack/transformers/ns-replace-lazy-loader': { nsReplaceLazyLoader: () => { return FakeLazyTransformerFlag } },
4952
'nativescript-dev-webpack/transformers/ns-support-hmr-ng': { nsSupportHmrNg: () => { return FakeHmrTransformerFlag } },
5053
'nativescript-dev-webpack/utils/ast-utils': { getMainModulePath: () => { return "fakePath"; } },
51-
'nativescript-dev-webpack/utils/tsconfig-utils': { getNoEmitOnErrorFromTSConfig: () => { return false; } },
54+
'nativescript-dev-webpack/utils/tsconfig-utils': { getNoEmitOnErrorFromTSConfig: () => { return false; }, getCompilerOptionsFromTSConfig: () => { return false; } },
5255
'nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin': { getAngularCompilerPlugin: () => { return AngularCompilerStub; } },
5356
'@ngtools/webpack': {
5457
AngularCompilerPlugin: AngularCompilerStub
@@ -59,7 +62,7 @@ const webpackConfigAngular = proxyquire('./webpack.angular', {
5962
const webpackConfigTypeScript = proxyquire('./webpack.typescript', {
6063
'nativescript-dev-webpack': nativeScriptDevWebpack,
6164
'nativescript-dev-webpack/nativescript-target': emptyObject,
62-
'nativescript-dev-webpack/utils/tsconfig-utils': { getNoEmitOnErrorFromTSConfig: () => { return false; } },
65+
'nativescript-dev-webpack/utils/tsconfig-utils': { getNoEmitOnErrorFromTSConfig: () => { return false; }, getCompilerOptionsFromTSConfig: () => { return false; } },
6366
'terser-webpack-plugin': TerserJsStub
6467
});
6568

@@ -362,6 +365,7 @@ describe('webpack.config.js', () => {
362365
describe(`alias for webpack.${type}.js (${platform})`, () => {
363366
it('should add alias when @nativescript/core is at the root of node_modules', () => {
364367
nativeScriptDevWebpack.hasRootLevelScopedModules = () => true;
368+
nativeScriptDevWebpack.hasRootLevelScopedAngular = () => true;
365369
const input = getInput({ platform });
366370
const config = webpackConfig(input);
367371
expect(config.resolve.alias['tns-core-modules']).toBe('@nativescript/core');
@@ -371,6 +375,7 @@ describe('webpack.config.js', () => {
371375
});
372376
it('shouldn\'t add alias when @nativescript/core is not at the root of node_modules', () => {
373377
nativeScriptDevWebpack.hasRootLevelScopedModules = () => false;
378+
nativeScriptDevWebpack.hasRootLevelScopedAngular = () => false;
374379
const input = getInput({ platform });
375380
const config = webpackConfig(input);
376381
expect(config.resolve.alias['tns-core-modules']).toBeUndefined();

0 commit comments

Comments
 (0)