UNPKG

next-yak

Version:

next-yak is a CSS-in-JS solution tailored for Next.js that seamlessly combines the expressive power of styled-components syntax with efficient build-time extraction of CSS using Next.js's built-in CSS configuration

125 lines (123 loc) 4.51 kB
import { existsSync } from "node:fs"; import path, { dirname } from "node:path"; import { fileURLToPath } from "node:url"; //#region withYak/index.ts const currentDir = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url)); const addYak = (yakOptions, nextConfig) => { const minify = yakOptions.minify ?? process.env.NODE_ENV === "production"; const yakPluginOptions = { minify, basePath: currentDir, prefix: yakOptions.prefix, displayNames: yakOptions.displayNames ?? !minify, suppressDeprecationWarnings: yakOptions.experiments?.suppressDeprecationWarnings ?? false, reactRefreshReg: true }; const transpilation = yakOptions.experiments?.transpilationMode ?? "CssModule"; const cssExtension = transpilation === "CssModule" ? ".yak.module.css" : ".yak.css"; if (process.env.TURBOPACK === "1" || process.env.TURBOPACK === "auto") addYakTurbopack(nextConfig, yakOptions, { ...yakPluginOptions, importMode: { value: "data:text/css;base64,", transpilation: "Css", encoding: "Base64" } }); else addYakWebpack(nextConfig, yakOptions, { ...yakPluginOptions, importMode: { value: `./{{__BASE_NAME__}}${cssExtension}!=!./{{__BASE_NAME__}}?./{{__BASE_NAME__}}${cssExtension}`, transpilation, encoding: "None" } }); return nextConfig; }; function addYakTurbopack(nextConfig, yakOptions, yakPluginOptions) { const yakLoader = removeUndefinedRecursive({ loader: path.join(currentDir, "../loaders/turbo-loader.cjs"), options: { yakOptions, yakPluginOptions } }); nextConfig.turbopack ||= {}; nextConfig.turbopack.rules ||= {}; const ruleKey = "*.{js,jsx,cjs,mjs,ts,tsx,cts,mts}"; const rule = { loaders: [], ...nextConfig.turbopack.rules[ruleKey] }; rule.loaders.push(yakLoader); nextConfig.turbopack.rules[ruleKey] = rule; const yakContext = resolveYakContext(yakOptions.contextPath, process.cwd()); if (yakContext) { nextConfig.turbopack.resolveAlias ||= {}; nextConfig.turbopack.resolveAlias["next-yak/context/baseContext"] = `./${path.relative(process.cwd(), yakContext)}`; } } function addYakWebpack(nextConfig, yakOptions, yakPluginOptions) { nextConfig.experimental ||= {}; nextConfig.experimental.swcPlugins ||= []; nextConfig.experimental.swcPlugins.push(["yak-swc", yakPluginOptions]); const previousConfig = nextConfig.webpack; nextConfig.webpack = (webpackConfig, options) => { if (previousConfig) webpackConfig = previousConfig(webpackConfig, options); webpackConfig.module.rules.push({ test: yakOptions.experiments?.transpilationMode === "Css" ? /\.yak\.css$/ : /\.yak\.module\.css$/, loader: path.join(currentDir, "../loaders/webpack-loader.cjs"), options: yakOptions }); const yakContext = resolveYakContext(yakOptions.contextPath, webpackConfig.context || process.cwd()); if (yakContext) webpackConfig.resolve.alias["next-yak/context/baseContext"] = yakContext; return webpackConfig; }; } function removeUndefinedRecursive(obj) { if (typeof obj !== "object" || obj === null) return obj; if (Array.isArray(obj)) { const filtered = []; for (let i = 0; i < obj.length; i++) { const processed = removeUndefinedRecursive(obj[i]); if (processed !== void 0) filtered.push(processed); } return filtered; } const newObj = {}; let hasChanges = false; for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = removeUndefinedRecursive(obj[key]); if (value !== void 0) { newObj[key] = value; hasChanges = true; } } return hasChanges ? newObj : obj; } function resolveYakContext(contextPath, cwd) { const yakContext = contextPath ? path.resolve(cwd, contextPath) : path.resolve(cwd, "yak.context"); const extensions = [ "", ".ts", ".tsx", ".js", ".jsx" ]; for (const extension in extensions) { const fileName = yakContext + extensions[extension]; if (existsSync(fileName)) return fileName; } if (contextPath) throw new Error(`Could not find yak context file at ${yakContext}`); } const withYak = (maybeYakOptions, nextConfig) => { if (nextConfig === void 0) return withYak({}, maybeYakOptions); const yakOptions = maybeYakOptions; if (typeof nextConfig === "function") return (...args) => { const config = nextConfig(...args); return config instanceof Promise ? config.then((config) => addYak(yakOptions, config)) : addYak(yakOptions, config); }; return addYak(yakOptions, nextConfig); }; //#endregion export { resolveYakContext, withYak }; //# sourceMappingURL=index.js.map