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,
|
getPlatform,
|
||||||
} from '../helpers/project';
|
} from '../helpers/project';
|
||||||
import { hasDependency } from '../helpers/dependencies';
|
import { hasDependency } from '../helpers/dependencies';
|
||||||
|
import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
|
||||||
|
|
||||||
export default function (config: Config, env: IWebpackEnv): Config {
|
export default function (config: Config, env: IWebpackEnv): Config {
|
||||||
const entryPath = getEntryPath();
|
const entryPath = getEntryPath();
|
||||||
@ -28,6 +29,10 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
|||||||
// set mode
|
// set mode
|
||||||
config.mode(mode);
|
config.mode(mode);
|
||||||
|
|
||||||
|
// config.stats({
|
||||||
|
// logging: 'verbose'
|
||||||
|
// })
|
||||||
|
|
||||||
// package.json is generated by the CLI with runtime options
|
// package.json is generated by the CLI with runtime options
|
||||||
// this ensures it's not included in the bundle, but rather
|
// this ensures it's not included in the bundle, but rather
|
||||||
// resolved at runtime
|
// 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
|
// todo: refine defaults
|
||||||
config.plugin('DefinePlugin').use(DefinePlugin, [
|
config.plugin('DefinePlugin').use(DefinePlugin, [
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
||||||
|
import { ContextExclusionPlugin } from 'webpack';
|
||||||
import Config from 'webpack-chain';
|
import Config from 'webpack-chain';
|
||||||
import dedent from 'ts-dedent';
|
import dedent from 'ts-dedent';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
@ -15,7 +16,12 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
|||||||
|
|
||||||
config.entry('bundle').add(virtualEntryPath);
|
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, [
|
config.plugin('VirtualModulesPlugin').use(VirtualModulesPlugin, [
|
||||||
{
|
{
|
||||||
[virtualEntryPath]: dedent`
|
[virtualEntryPath]: dedent`
|
||||||
@ -26,6 +32,8 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
config.resolve.extensions.add('.xml');
|
||||||
|
|
||||||
// set up xml
|
// set up xml
|
||||||
config.module
|
config.module
|
||||||
.rule('xml')
|
.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