wip: RuntimePackageJSONPlugin

This commit is contained in:
Igor Randjelovic
2024-08-14 02:03:11 +02:00
parent dca77183d1
commit 6623067c72
3 changed files with 81 additions and 11 deletions

View File

@ -13,6 +13,7 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import TerserPlugin from 'terser-webpack-plugin';
import { getProjectFilePath, getProjectTSConfigPath } from '../helpers/project';
import { RuntimePackageJSONPlugin } from '../plugins/RuntimePackageJSONPlugin';
import { getDependencyVersion, hasDependency } from '../helpers/dependencies';
import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
import { applyFileReplacements } from '../helpers/fileReplacements';
@ -20,7 +21,7 @@ import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
import { applyDotEnvPlugin } from '../helpers/dotEnv';
import { env as _env, IWebpackEnv } from '../index';
import { getValue } from '../helpers/config';
import { getValue, getValueFallbacks } from '../helpers/config';
import { getIPS } from '../helpers/host';
import {
getAvailablePlatforms,
@ -46,7 +47,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
// package.json is generated by the CLI with runtime options
// this ensures it's not included in the bundle, but rather
// resolved at runtime
config.externals(['package.json', '~/package.json']);
// config.externals(['package.json', '~/package.json']);
// disable marking built-in node modules as external
// since they are not available at runtime and
@ -87,7 +88,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
const sourceMapAbsolutePath = getProjectFilePath(
`./${
env.buildPath ?? 'platforms'
}/${platform}-sourceMaps/[file].map[query]`,
}/${platform}-sourceMaps/[file].map[query]`
);
const sourceMapRelativePath = relative(outputPath, sourceMapAbsolutePath);
config.output.sourceMapFilename(sourceMapRelativePath);
@ -273,7 +274,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
const configFile = tsConfigPath
? {
configFile: tsConfigPath,
}
}
: undefined;
// set up ts support
@ -353,7 +354,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
const extPath = resolve(baseDir, platformRequest);
try {
return require.resolve(platformRequest, {
return (require as NodeRequire).resolve(platformRequest, {
paths: [baseDir],
});
} catch {}
@ -452,7 +453,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
* +-----------------------------------------------------------------------------------------+
*/
/System.import\(\) is deprecated/,
]),
])
);
// todo: refine defaults
@ -494,6 +495,14 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
applyCopyRules(config);
// Emit a package.json file to be used at runtime containing the runtime options for the app
config.plugin('RuntimePackageJSONPlugin').use(RuntimePackageJSONPlugin, [
{
...getValue<Record<string, any>>('.', {}),
...getValue<Record<string, any>>(platform, {}),
},
]);
config.plugin('WatchStatePlugin').use(WatchStatePlugin);
config.when(env.hmr, (config) => {

View File

@ -1,6 +1,11 @@
import { warnOnce } from './log';
import { env } from '../index';
interface IPartialProjectConfigService {
readConfig(projectDir?: string): Record<string, any>;
getValue<T = any>(key: string, defaultValue?: any): T;
}
function getCLILib() {
if (!env.nativescriptLibPath) {
if (typeof env.nativescriptLibPath !== 'boolean') {
@ -34,9 +39,35 @@ export function getValue<T = any>(key: string, defaultValue?: any): T {
return defaultValue;
}
return (
lib.projectConfigService as {
getValue(key: string, defaultValue?: any): T;
}
).getValue(key, defaultValue);
if (key === '.') {
return (
lib.projectConfigService as IPartialProjectConfigService
).readConfig() as T;
}
return (lib.projectConfigService as IPartialProjectConfigService).getValue(
key,
defaultValue
);
}
/**
* Utility to get a value from multiple keys in the nativescript.config.ts file, until one is found, or return a default value.
*
* @param keys a list of keys to try to get the value from
* @param defaultValue The fallback value if none of the keys are set in the config.
* @returns
*/
export function getValueFallbacks<T = any>(
keys: string[],
defaultValue?: any
): T {
for (const key of keys) {
const value = getValue<T>(key);
if (value) {
return value;
}
}
return defaultValue;
}

View File

@ -0,0 +1,30 @@
import webpack from 'webpack';
const id = 'RuntimePackageJSONPlugin';
/**
* The platform suffix plugin will try to resolve files with a platform specifier (suffix)
* falling back to the non-platform-specific version.
*
* For example:
* import something from './something.js'
*
* will first look for './something.<platform>.js'
* and if not found look for './something.js'
*
*/
export class RuntimePackageJSONPlugin {
constructor(private additionalContents: Record<string, any>) {}
apply(compiler: webpack.Compiler) {
compiler.hooks.compilation.tap(id, (compilation) => {
compilation.assets['package.json'] = new webpack.sources.RawSource(
JSON.stringify(
Object.assign({}, this.additionalContents, { main: 'bundle' }),
null,
2
)
);
});
}
}