mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-14 18:12:09 +08:00
feat: platform suffix resolution [wip]
This commit is contained in:
@ -18,6 +18,7 @@ import {
|
||||
getPlatform,
|
||||
} from '../helpers/project';
|
||||
import { hasDependency } from '../helpers/dependencies';
|
||||
import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv): Config {
|
||||
const entryPath = getEntryPath();
|
||||
@ -28,6 +29,10 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
// set mode
|
||||
config.mode(mode);
|
||||
|
||||
// config.stats({
|
||||
// logging: 'verbose'
|
||||
// })
|
||||
|
||||
// package.json is generated by the CLI with runtime options
|
||||
// this ensures it's not included in the bundle, but rather
|
||||
// resolved at runtime
|
||||
@ -194,6 +199,22 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
},
|
||||
]);
|
||||
|
||||
// config.plugin('NormalModuleReplacementPlugin').use(NormalModuleReplacementPlugin, [
|
||||
// /.*/,
|
||||
// request => {
|
||||
// if (new RegExp(`\.${platform}\..+$`).test(request.request)) {
|
||||
// request.rawRequest = request.rawRequest.replace(`.${platform}.`, '.')
|
||||
// console.log(request)
|
||||
// }
|
||||
// }
|
||||
// ])
|
||||
|
||||
config.plugin('PlatformSuffixPlugin').use(PlatformSuffixPlugin, [
|
||||
{
|
||||
platform,
|
||||
},
|
||||
]);
|
||||
|
||||
// todo: refine defaults
|
||||
config.plugin('DefinePlugin').use(DefinePlugin, [
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
||||
import { ContextExclusionPlugin } from 'webpack';
|
||||
import Config from 'webpack-chain';
|
||||
import dedent from 'ts-dedent';
|
||||
import { join } from 'path';
|
||||
@ -15,7 +16,12 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
|
||||
config.entry('bundle').add(virtualEntryPath);
|
||||
|
||||
// Add a virtual entry module
|
||||
config
|
||||
.plugin('ContextExclusionPluginPlugin')
|
||||
.use(ContextExclusionPlugin, [/__virtual_entry__\.js$/]);
|
||||
|
||||
// Add a virtual entry module that will register all modules into
|
||||
// the nativescript module loader/handler
|
||||
config.plugin('VirtualModulesPlugin').use(VirtualModulesPlugin, [
|
||||
{
|
||||
[virtualEntryPath]: dedent`
|
||||
@ -26,6 +32,8 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
},
|
||||
]);
|
||||
|
||||
config.resolve.extensions.add('.xml');
|
||||
|
||||
// set up xml
|
||||
config.module
|
||||
.rule('xml')
|
||||
|
152
packages/webpack5/src/plugins/PlatformSuffixPlugin.ts
Normal file
152
packages/webpack5/src/plugins/PlatformSuffixPlugin.ts
Normal file
@ -0,0 +1,152 @@
|
||||
import { existsSync } from 'fs';
|
||||
import { extname, resolve } from 'path';
|
||||
|
||||
const id = 'PlatformSuffixPlugin';
|
||||
|
||||
interface PlatformSuffixPluginOptions {
|
||||
platform: string;
|
||||
// extensions: string[] | (() => string[])
|
||||
}
|
||||
|
||||
export class PlatformSuffixPlugin {
|
||||
private readonly platform: string;
|
||||
// private readonly extensions: string[]
|
||||
|
||||
constructor(options: PlatformSuffixPluginOptions) {
|
||||
this.platform = options.platform;
|
||||
|
||||
// if (typeof options.extensions === "function") {
|
||||
// this.extensions = options.extensions()
|
||||
// } else {
|
||||
// this.extensions = options.extensions
|
||||
// }
|
||||
}
|
||||
|
||||
apply(compiler: any) {
|
||||
console.log(
|
||||
// this.extensions,
|
||||
this.platform
|
||||
);
|
||||
const platformRE = new RegExp(`\.${this.platform}\.`);
|
||||
|
||||
compiler.hooks.contextModuleFactory.tap(id, (cmf) => {
|
||||
cmf.hooks.alternativeRequests.tap(id, (modules, options) => {
|
||||
const additionalModules = [];
|
||||
// we are looking for modules that are platform specific (something.<platform>.ext)
|
||||
// and we are duplicating them without the platform suffix
|
||||
// this allows using require.context with non-existent platformless filenames
|
||||
// but mapped to the platform specific variant (done in the resolver hook below)
|
||||
for (const module of modules) {
|
||||
if (platformRE.test(module.request)) {
|
||||
additionalModules.push({
|
||||
...module,
|
||||
request: module.request.replace(platformRE, '.'),
|
||||
});
|
||||
}
|
||||
}
|
||||
modules.push(...additionalModules);
|
||||
});
|
||||
});
|
||||
|
||||
compiler.resolverFactory.hooks.resolver
|
||||
.for('normal')
|
||||
.tap(id, (resolver) => {
|
||||
// Object.keys(resolver.hooks).forEach(hook => {
|
||||
// resolver.hooks[hook].tap(id, (request, resolveContext) => {
|
||||
// if(
|
||||
// request?.path?.includes('foo.xml') ||
|
||||
// request?.request?.includes('foo.xml')
|
||||
// ) {
|
||||
// console.log(
|
||||
// `>>> ${hook}: ${request.path}`,
|
||||
// // request
|
||||
// )
|
||||
// }
|
||||
// // callback();
|
||||
// });
|
||||
// })
|
||||
|
||||
resolver.hooks.normalResolve.tapAsync(
|
||||
id,
|
||||
(request_, resolveContext, callback) => {
|
||||
const { path, request } = request_;
|
||||
const ext = request && extname(request);
|
||||
const platformExt = ext ? `.${this.platform}${ext}` : '';
|
||||
|
||||
if (path && request && ext && !request.includes(platformExt)) {
|
||||
const platformRequest = request.replace(ext, platformExt);
|
||||
const extPath = resolve(path, platformRequest);
|
||||
|
||||
// console.log({
|
||||
// path,
|
||||
// request,
|
||||
// ext,
|
||||
// extPath
|
||||
// })
|
||||
|
||||
// if a file with the same + a platform suffix exists
|
||||
// we want to resolve that file instead
|
||||
if (existsSync(extPath)) {
|
||||
const message = `resolving "${request}" to "${platformRequest}"`;
|
||||
const hook = resolver.ensureHook('normalResolve');
|
||||
console.log(message);
|
||||
|
||||
// here we are creating a new resolve object and replacing the path
|
||||
// with the .<platform>.<ext> suffix
|
||||
const obj = {
|
||||
...request_,
|
||||
path: resolver.join(path, platformRequest),
|
||||
relativePath:
|
||||
request_.relativePath &&
|
||||
resolver.join(request_.relativePath, platformRequest),
|
||||
request: undefined,
|
||||
};
|
||||
|
||||
// we call to the actual resolver to do the resolving of this new file
|
||||
return resolver.doResolve(
|
||||
hook,
|
||||
obj,
|
||||
message,
|
||||
resolveContext,
|
||||
callback
|
||||
);
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
);
|
||||
// resolver.hooks.rawFile.tap(id, (request, resolveContext, callback) => {
|
||||
// if(request.path && !/\.ios\..+$/.test(request.path)) {
|
||||
// const { ext } = parse(request.path)
|
||||
// const platformExtPath = request.path.replace(ext, `.${this.platform}${ext}`)
|
||||
// // console.log({
|
||||
// // p1: request.path,
|
||||
// // p2: platformExtPath
|
||||
// // })
|
||||
// if(existsSync(platformExtPath)) {
|
||||
// // request.path = platformExtPath
|
||||
// // console.log('-'.repeat(100))
|
||||
// // console.log(request)
|
||||
// const obj = {
|
||||
// ...request,
|
||||
// path: platformExtPath,
|
||||
// fullySpecified: false
|
||||
// }
|
||||
// return resolver.doResolve(
|
||||
// 'raw-file',
|
||||
// obj,
|
||||
// `resolved ${request.path} to platform specific file: ${platformExtPath}`,
|
||||
// resolveContext,
|
||||
// (err, result) => {
|
||||
// if(err) return callback(err);
|
||||
// if(result) return callback(null, result);
|
||||
// return callback();
|
||||
// }
|
||||
// )
|
||||
// // return request
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user