diff --git a/README.md b/README.md index 175ba41..496c3f7 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,10 @@ Use this option to configure how the rule solve paths of `@import` rules. "resolver": { "extensions": [".css"], // => default to [".css"] "paths": ["./assets/css", "./static/css"], // => paths to look for files, default to [] - "moduleDirectories": ["node_modules"] // => modules folder to look for files, default to ["node_modules"] + "moduleDirectories": ["node_modules"], // => modules folder to look for files, default to ["node_modules"] + "alias": { + "@": resolve(import.meta.dirname, 'src') // => Alias for import path + } } }] } diff --git a/index.test.mjs b/index.test.mjs index 641248b..a66434a 100644 --- a/index.test.mjs +++ b/index.test.mjs @@ -44,10 +44,22 @@ accept = [ { code: '@import url("./test/import-custom-properties.css" url-mod); body { color: var(--brand-red); }' }, { code: '@import \'./test/import-custom-properties.css\'; @import \'./test/import-custom-properties123.css\'; body { color: var(--brand-red); }' }, { code: 'color: var(--my-undefined-color, #ffffff);' }, + { code: '@use \'./test/import-custom-properties.css\'; body { color: var(--brand-red); }' }, + { code: '@use "./test/import-custom-properties.css" screen; body { color: var(--brand-red); }' }, + { code: '@use "./test/import-custom-properties.css"/**/; body { color: var(--brand-red); }' }, + { code: '@use url(./test/import-custom-properties.css); body { color: var(--brand-red); }' }, + { code: '@use url(\'./test/import-custom-properties.css\'); body { color: var(--brand-red); }' }, + { code: '@use url( \'./test/import-custom-properties.css\'/**/)/**/; body { color: var(--brand-red); }' }, + { code: '@use url(\t\'./test/import-custom-properties.css\'\t)\t; body { color: var(--brand-red); }' }, + { code: '@use url(./test/import-custom-properties.css) screen; body { color: var(--brand-red); }' }, + { code: '@use url("./test/import-custom-properties.css") screen; body { color: var(--brand-red); }' }, + { code: '@use url("./test/import-custom-properties.css" url-mod); body { color: var(--brand-red); }' }, + { code: '@use \'./test/import-custom-properties.css\'; @import \'./test/import-custom-properties123.css\'; body { color: var(--brand-red); }' }, ]; reject = [ { code: 'body { color: var(--brand-blue); }', message: messages.unexpected('--brand-blue', 'color') }, { code: '@import \'./test/import-custom-properties123.css\'; body { color: var(--brand-red); }', message: messages.unexpected('--brand-red', 'color') }, + { code: '@use \'./test/import-custom-properties123.css\'; body { color: var(--brand-red); }', message: messages.unexpected('--brand-red', 'color') }, ]; testRule({ plugins: ['.'], ruleName: rule.ruleName, config: true, accept, reject }); @@ -145,3 +157,34 @@ testRule({ accept, reject, }); + +/* Test enabled: { resolver: { alias } } +/* ========================================================================== */ + +accept = [ + { code: '@import \'@/import-custom-properties.css\'; body { color: var(--brand-red); }' }, + { code: '@import \'@test/import-custom-properties.css\'; body { color: var(--brand-red); }' }, + { code: '@use \'@/import-custom-properties.css\'; body { color: var(--brand-red); }' }, + { code: '@use \'@test/import-custom-properties.css\'; body { color: var(--brand-red); }' }, +]; +reject = [ + { code: '@import \'@/import-custom-properties.css\'; body { color: var(--brand-re); }', message: messages.unexpected('--brand-re', 'color') }, + { code: '@import \'@/import-custom-properties.css\'; body { color: var(--brand-redz); }', message: messages.unexpected('--brand-redz', 'color') }, + { code: '@use \'@/import-custom-properties.css\'; body { color: var(--brand-re); }', message: messages.unexpected('--brand-re', 'color') }, + { code: '@use \'@/import-custom-properties.css\'; body { color: var(--brand-redz); }', message: messages.unexpected('--brand-redz', 'color') }, +]; + +testRule({ + plugins: ['.'], + ruleName: rule.ruleName, + config: [true, { + resolver: { + alias: { + '@': './test', + '@test': './test', + }, + }, + }], + accept, + reject, +}); \ No newline at end of file diff --git a/src/lib/get-custom-properties-from-root.mjs b/src/lib/get-custom-properties-from-root.mjs index 2e3a7c1..4698038 100644 --- a/src/lib/get-custom-properties-from-root.mjs +++ b/src/lib/get-custom-properties-from-root.mjs @@ -18,22 +18,15 @@ export default async function getCustomPropertiesFromRoot(root, resolver) { // recursively add custom properties from @import statements const importPromises = []; root.walkAtRules('import', atRule => { - const fileName = parseImportParams(atRule.params); - if (!fileName) { - return; + const promise = getImportPromise(atRule, resolver, sourceDir); + if (promise) { + importPromises.push(promise); } + }); - if (path.isAbsolute(fileName)) { - importPromises.push(getCustomPropertiesFromCSSFile(fileName, resolver)); - } else { - const promise = resolveId(fileName, sourceDir, { - paths: resolver.paths, - extensions: resolver.extensions, - moduleDirectories: resolver.moduleDirectories, - }) - .then((filePath) => getCustomPropertiesFromCSSFile(filePath, resolver)) - .catch(() => {}); - + root.walkAtRules('use', atRule => { + const promise = getImportPromise(atRule, resolver, sourceDir); + if (promise) { importPromises.push(promise); } }); @@ -107,3 +100,44 @@ function parseImportParams(params) { return false; } + +function getFileNameFromAlias(fileName, resolver) { + if (!resolver.alias) { + return fileName; + } + + const split = fileName.split('/'); + + if (split.length > 0) { + const resolvedAlias = Object.entries(resolver.alias).find(([key]) => key === split[0]); + + if (resolvedAlias) { + const [alias, value] = resolvedAlias; + return fileName.replace(alias, value); + } + } + return fileName; +} + +function getImportPromise(atRule, resolver, sourceDir) { + const fileName = parseImportParams(atRule.params); + if (!fileName) { + return; + } + + const aliasedFileName = getFileNameFromAlias(fileName, resolver); + + if (path.isAbsolute(fileName)) { + return getCustomPropertiesFromCSSFile(aliasedFileName, resolver); + } else { + const promise = resolveId(aliasedFileName, sourceDir, { + paths: resolver.paths, + extensions: resolver.extensions, + moduleDirectories: resolver.moduleDirectories, + }) + .then((filePath) => getCustomPropertiesFromCSSFile(filePath, resolver)) + .catch(() => {}); + + return promise; + } +} \ No newline at end of file