UNPKG

gatsby-plugin-dts-css-modules

Version:

GatsbyJS V4 plugin, which automatically Creates TypeScript *.d.ts files for your CSS Modules, no matter which CSS preprocessor (Sass, LESS, Stylus etc.) you are using.

112 lines (93 loc) 2.86 kB
const defaultBanner = '// This file is automatically generated. Do not modify this file manually -- YOUR CHANGES WILL BE ERASED!'; /** @type {import('gatsby').GatsbyNode} */ module.exports = { onCreateWebpackConfig: ({ getConfig, actions }, options) => { /** @type {import('webpack').Configuration} */ const config = getConfig(); if (!config.module?.rules) { return; } for (const rule of config.module.rules) { if (typeof rule === 'string') { return; } if ('oneOf' in rule && rule.oneOf !== undefined) { for (const oneOf of rule.oneOf) { injectBeforeCSSLoader(oneOf, options); } } else { injectBeforeCSSLoader(rule, options); } } actions.replaceWebpackConfig(config); }, pluginOptionsSchema: ({ Joi }) => Joi.object({ namedExport: Joi .boolean() .description('When the option is switched on classes exported as variables.') .default(true), banner: Joi .string() .description('Adds a "banner" prefix to each generated file.') .default(defaultBanner), customTypings: Joi .function() .description('A function that accepts classes (an array of string) and returns the content of declaration file.') .arity(1), dropEmptyFile: Joi .boolean() .description('If there are no classes, the typings file will not be generated, and the existing will be deleted.') }) } /** * Place the `dts-css-modules-loader` before the `css-loader` if it exist. * * @param {import('webpack').RuleSetRule} rule * @param {import('gatsby').PluginOptions | undefined} options * @returns {void} */ function injectBeforeCSSLoader (rule, options) { if (!Array.isArray(rule.use)) { return; } const cssLoaderPath = getCSSLoaderPath(); for (let index = 0; index < rule.use.length; index++) { const loader = rule.use[index]; if ( (typeof loader === 'string' && loader === cssLoaderPath) || (typeof loader === 'object' && loader.loader === cssLoaderPath && isCSSModulesLoader(loader)) ) { rule.use.splice(index, 0, { loader: require.resolve('dts-css-modules-loader'), options: { namedExport: true, banner: defaultBanner, ...options } }); return; } } } /** * Find the path to "css-loader" from gatsby's point of view. * * @returns {string} */ function getCSSLoaderPath () { const resolveDefaultPaths = require.resolve.paths('css-loader') || []; return require.resolve('css-loader', { paths: [require.resolve('gatsby'), ...resolveDefaultPaths] }) } /** * Basic detection of whether the CSS Modules option is activated in an object-based `css-loader` configuration. * * @param {Exclude<import('webpack').RuleSetUseItem, string | Function>} loader * @returns */ function isCSSModulesLoader (loader) { if (typeof loader.options === 'object') { return (loader.options.modules !== false); } return true; }