feat(webpack): angular configuration support for environment handling (#8938)

This commit is contained in:
Nathan Walker
2020-10-06 08:19:15 -07:00
committed by GitHub
parent 0f494d2cb2
commit 3f7bf676ff
3 changed files with 134 additions and 3 deletions

View File

@ -0,0 +1,104 @@
const { resolve } = require('path');
const fs = require('fs');
const parseWorkspaceConfig = function(platform, envConfigs, projectName, debug) {
if (debug) {
console.log('-- config DEBUG ---');
console.log('platform:', platform);
console.log('configuration:', envConfigs);
}
// configuration file replacements
const fileReplacements = {};
// anything other than .ts files should be added as part of copy plugin
const copyReplacements = [];
if (hasConfigurations(envConfigs)) {
envConfigs = envConfigs.split(',').map(e => e.trim());
const configData = findConfig(__dirname);
const rootPath = configData.rootPath;
const workspaceConfig = configData.workspaceConfig;
if (workspaceConfig && projectName) {
const projectSettings = workspaceConfig.projects[projectName];
if (projectSettings) {
// default project configurations
for (const envConfig of envConfigs) {
if (projectSettings.configurations && projectSettings.configurations[envConfig]) {
if (projectSettings.configurations[envConfig].fileReplacements) {
for (const fileReplace of projectSettings.configurations[envConfig].fileReplacements) {
if (debug) {
console.log('project fileReplacement:', fileReplace);
}
if (fileReplace.replace.indexOf('.ts') > -1) {
fileReplacements[resolve(__dirname, `${rootPath}${fileReplace.replace}`)] = resolve(__dirname, `${rootPath}${fileReplace.with}`);
} else {
copyReplacements.push({ from: resolve(__dirname, `${rootPath}${fileReplace.with}`), to: resolve(__dirname, `${rootPath}${fileReplace.replace}`), force: true });
}
}
}
}
}
// platform specific configurations (always override top level project configurations)
for (const envConfig of envConfigs) {
if (projectSettings.architect && projectSettings.architect[platform]) {
const platformConfig = projectSettings.architect[platform].configurations;
if (platformConfig && platformConfig[envConfig] && platformConfig[envConfig].fileReplacements) {
for (const fileReplace of platformConfig[envConfig].fileReplacements) {
if (debug) {
console.log(`"${platform}" specific fileReplacement:`, fileReplace);
}
if (fileReplace.replace.indexOf('.ts') > -1) {
fileReplacements[resolve(__dirname, `${rootPath}${fileReplace.replace}`)] = resolve(__dirname, `${rootPath}${fileReplace.with}`);
} else {
copyReplacements.push({ from: resolve(__dirname, `${rootPath}${fileReplace.with}`), to: resolve(__dirname, `${rootPath}${fileReplace.replace}`), force: true });
}
}
}
}
}
}
}
}
if (debug && copyReplacements.length) {
console.log('Adding to CopyWebpackPlugin:', copyReplacements);
}
return {
fileReplacements,
copyReplacements
};
}
const findConfig = function(projectDir, rootPath = '') {
// support workspace.json and angular.json configurations
const angularConfigName = 'angular.json';
const angularConfig = resolve(projectDir, angularConfigName);
const workspaceConfigName = 'workspace.json';
const workspaceConfig = resolve(projectDir, workspaceConfigName);
if (fs.existsSync(workspaceConfig)) {
return {
rootPath,
workspaceConfig: require(workspaceConfig)
};
} else if (fs.existsSync(angularConfig)) {
return {
rootPath,
workspaceConfig: require(angularConfig)
};
} else {
rootPath += '../';
return findConfig(resolve(projectDir, '..'), rootPath);
}
}
const hasConfigurations = function(envConfigs) {
return envConfigs && envConfigs !== 'undefined';
}
module.exports = {
parseWorkspaceConfig,
findConfig,
hasConfigurations
};

View File

@ -8,6 +8,9 @@ const {
nsSupportHmrNg nsSupportHmrNg
} = require('@nativescript/webpack/transformers/ns-support-hmr-ng'); } = require('@nativescript/webpack/transformers/ns-support-hmr-ng');
const { nsTransformNativeClassesNg } = require("@nativescript/webpack/transformers/ns-transform-native-classes-ng"); const { nsTransformNativeClassesNg } = require("@nativescript/webpack/transformers/ns-transform-native-classes-ng");
const {
parseWorkspaceConfig, hasConfigurations
} = require('@nativescript/webpack/helpers/angular-config-parser');
const { const {
getMainModulePath getMainModulePath
} = require('@nativescript/webpack/utils/ast-utils'); } = require('@nativescript/webpack/utils/ast-utils');
@ -54,6 +57,8 @@ module.exports = env => {
// You can provide the following flags when running 'tns run android|ios' // You can provide the following flags when running 'tns run android|ios'
snapshot, // --env.snapshot, snapshot, // --env.snapshot,
production, // --env.production production, // --env.production
configuration, // --env.configuration (consistent with angular cli usage)
projectName, // --env.projectName (drive configuration through angular projects)
uglify, // --env.uglify uglify, // --env.uglify
report, // --env.report report, // --env.report
sourceMap, // --env.sourceMap sourceMap, // --env.sourceMap
@ -68,20 +73,29 @@ module.exports = env => {
compileSnapshot // --env.compileSnapshot compileSnapshot // --env.compileSnapshot
} = env; } = env;
const { fileReplacements, copyReplacements } = parseWorkspaceConfig(platform, configuration, projectName);
const useLibs = compileSnapshot; const useLibs = compileSnapshot;
const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
const externals = nsWebpack.getConvertedExternals(env.externals); const externals = nsWebpack.getConvertedExternals(env.externals);
const appFullPath = resolve(projectRoot, appPath); const appFullPath = resolve(projectRoot, appPath);
const appResourcesFullPath = resolve(projectRoot, appResourcesPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
let tsConfigName = 'tsconfig.json'; let tsConfigName = 'tsconfig.json';
let tsConfigTnsName = 'tsconfig.tns.json';
let tsConfigPath = resolve(projectRoot, tsConfigName); let tsConfigPath = resolve(projectRoot, tsConfigName);
const tsConfigTnsName = 'tsconfig.tns.json';
const tsConfigTnsPath = resolve(projectRoot, tsConfigTnsName); const tsConfigTnsPath = resolve(projectRoot, tsConfigTnsName);
if (fs.existsSync(tsConfigTnsPath)) { if (fs.existsSync(tsConfigTnsPath)) {
// still support shared angular app configurations // support shared angular app configurations
tsConfigName = tsConfigTnsName; tsConfigName = tsConfigTnsName;
tsConfigPath = tsConfigTnsPath; tsConfigPath = tsConfigTnsPath;
} }
const tsConfigEnvName = 'tsconfig.env.json';
const tsConfigEnvPath = resolve(projectRoot, tsConfigEnvName);
if (hasConfigurations(configuration) && fs.existsSync(tsConfigEnvPath)) {
// when configurations are used, switch to environments supported config
tsConfigName = tsConfigEnvName;
tsConfigPath = tsConfigEnvPath;
}
const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`; const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
const entryPath = `.${sep}${entryModule}`; const entryPath = `.${sep}${entryModule}`;
const entries = { bundle: entryPath }; const entries = { bundle: entryPath };
@ -104,6 +118,7 @@ module.exports = env => {
const copyTargets = [ const copyTargets = [
{ from: 'assets/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } }, { from: 'assets/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
{ from: 'fonts/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } }, { from: 'fonts/**', noErrorOnMissing: true, globOptions: { dot: false, ...copyIgnore } },
...copyReplacements
]; ];
if (!production) { if (!production) {
@ -217,7 +232,8 @@ module.exports = env => {
'~/package.json': resolve(projectRoot, 'package.json'), '~/package.json': resolve(projectRoot, 'package.json'),
'~': appFullPath, '~': appFullPath,
"tns-core-modules": "@nativescript/core", "tns-core-modules": "@nativescript/core",
"nativescript-angular": "@nativescript/angular" "nativescript-angular": "@nativescript/angular",
...fileReplacements
}, },
symlinks: true symlinks: true
}, },

View File

@ -57,6 +57,17 @@ const webpackConfigAngular = proxyquire('./webpack.angular', {
return FakeNativeClassTransformerFlag; return FakeNativeClassTransformerFlag;
}, },
}, },
'@nativescript/webpack/helpers/angular-config-parser': {
parseWorkspaceConfig: (platform, envConfigs, rootPath = '') => {
return {
fileReplacements: {},
copyReplacements: [],
};
},
hasConfigurations: (envConfigs) => {
return false;
}
},
'@nativescript/webpack/utils/ast-utils': { '@nativescript/webpack/utils/ast-utils': {
getMainModulePath: () => { getMainModulePath: () => {
return 'fakePath'; return 'fakePath';