@callstack/repack-plugin-nativewind
Version:
A plugin for @callstack/repack that integrates NativeWind
127 lines (126 loc) • 5.33 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NativeWindPlugin = void 0;
class NativeWindPlugin {
constructor(options = {}) {
this.options = options;
this.options.checkDependencies = this.options.checkDependencies ?? true;
}
configureSwcLoaderForNativeWind(swcOptions = {}) {
const options = structuredClone(swcOptions);
options.jsc = options.jsc ?? {};
options.jsc.transform = options.jsc.transform ?? {};
options.jsc.transform.react = options.jsc.transform.react ?? {};
options.jsc.transform.react.runtime = 'automatic';
options.jsc.transform.react.importSource = 'nativewind';
return options;
}
handleRuleUseField(ruleUseField) {
if (Array.isArray(ruleUseField)) {
return ruleUseField.map((item) => this.handleRuleUseField(item));
}
if (typeof ruleUseField === 'function') {
console.warn('[RepackNativeWindPlugin] Dynamic loader configurations using functions are not supported. ' +
'If you are using builtin:swc-loader, please manually set jsc.transform.react.importSource to "nativewind" in its configuration.');
}
else if (typeof ruleUseField === 'string') {
if (ruleUseField === 'builtin:swc-loader') {
return {
loader: 'builtin:swc-loader',
options: this.configureSwcLoaderForNativeWind({}),
};
}
}
else if (ruleUseField.loader === 'builtin:swc-loader') {
ruleUseField.options = this.configureSwcLoaderForNativeWind(ruleUseField.options);
}
return ruleUseField;
}
handleRuleOptionsField(ruleOptionsField) {
return this.configureSwcLoaderForNativeWind(ruleOptionsField);
}
ensureDependencyInstalled(context, dependency) {
try {
require.resolve(dependency, { paths: [context] });
}
catch {
const error = new Error(`[RepackNativeWindPlugin] Dependency named '${dependency}' is required but not found in your project. ` +
'Did you forget to install it?');
// remove the stack trace to make the error more readable
error.stack = undefined;
throw error;
}
}
ensureNativewindDependenciesInstalled(context) {
const dependencies = [
'nativewind',
'react-native-css-interop',
'postcss',
'postcss-loader',
'tailwindcss',
'autoprefixer',
];
dependencies.forEach((dependency) => {
this.ensureDependencyInstalled(context, dependency);
});
}
apply(__compiler) {
const compiler = __compiler;
if (this.options.checkDependencies) {
this.ensureNativewindDependenciesInstalled(compiler.context);
}
/** Set the platform if not present*/
const platformName = compiler.options.name;
if (process.env.NATIVEWIND_OS === undefined) {
process.env.NATIVEWIND_OS = platformName;
}
/**
* First, we need to process the CSS files using PostCSS.
* The PostCSS loader will use Tailwind CSS to generate the necessary utility classes
* based on the content of the project files. It will also use Autoprefixer to add vendor prefixes.
* Finally, we need to convert the CSS to something React Native can process using a utility
* from nativewind (this is handled inside the repack-plugin-nativewind/loader).
*
* NOTE: loaders are run in reverse order, so the last loader in the array will be run first.
*/
compiler.options.module.rules.push({
test: /\.css$/,
use: [
{
loader: '@callstack/repack-plugin-nativewind/loader',
options: this.options.cssInteropOptions,
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
},
},
],
});
/**
* Second, we need to configure the `builtin:swc-loader` to properly handle NativeWind's JSX transformations.
* We look for any instances of the `builtin:swc-loader` in the Rspack configuration and modify their options
* to include the NativeWind react import source.
*
* TODO made obsolete by the new babel-swc-loader, remove in 6.0
*/
compiler.options.module.rules.forEach((rule) => {
if (!rule || typeof rule !== 'object') {
return;
}
if ('use' in rule && rule.use !== undefined) {
rule.use = this.handleRuleUseField(rule.use);
}
if ('loader' in rule && rule.loader === 'builtin:swc-loader') {
rule.options = this.handleRuleOptionsField(rule.options);
}
});
}
}
exports.NativeWindPlugin = NativeWindPlugin;