esbuild-css-modules-plugin
Advanced tools
Comparing version 2.0.2 to 2.0.3
218
index.js
const path = require('path'); | ||
const fs = require('fs-extra'); | ||
const fse = require('fs-extra'); | ||
const fs = require('fs'); | ||
const postcss = require('postcss'); | ||
@@ -9,5 +10,5 @@ const cssModules = require('postcss-modules'); | ||
const hash = crypto.createHash('sha256'); | ||
const readFile = util.promisify(fs.readFile); | ||
const writeFile = util.promisify(fs.writeFile); | ||
const ensureDir = util.promisify(fs.ensureDir); | ||
const readFile = util.promisify(fse.readFile); | ||
const writeFile = util.promisify(fse.writeFile); | ||
const ensureDir = util.promisify(fse.ensureDir); | ||
const pluginNamespace = 'esbuild-css-modules-plugin-namespace'; | ||
@@ -85,115 +86,116 @@ | ||
setup(build) { | ||
const tmpCsses = new Set(); | ||
const tmpFiles = new Set(); | ||
const rootDir = process.cwd(); | ||
const tmpDirPath = tmp.dirSync().name; | ||
const { outdir, bundle } = build.initialOptions; | ||
const { outdir, bundle, logLevel } = build.initialOptions; | ||
const { v2 } = options; | ||
build.onResolve({ filter: /\.modules?\.css$/, namespace: 'file' }, async (args) => { | ||
const sourceFullPath = path.resolve(args.resolveDir, args.path); | ||
const outputLogs = logLevel === 'debug' || logLevel === 'verbose'; | ||
const sourceExt = path.extname(sourceFullPath); | ||
const sourceBaseName = path.basename(sourceFullPath, sourceExt); | ||
const sourceDir = path.dirname(sourceFullPath); | ||
const sourceRelDir = path.relative(path.dirname(rootDir), sourceDir); | ||
const useV2 = v2 && bundle; | ||
const tmpDir = path.resolve(tmpDirPath, sourceRelDir); | ||
await ensureDir(tmpDir); | ||
const tmpFilePath = path.resolve(tmpDir, `${sourceBaseName}.css`); | ||
const { jsContent: _jsContent, cssContent } = await buildCssModulesJS(sourceFullPath, { | ||
...options, | ||
bundle | ||
if (useV2) { | ||
build.onResolve({ filter: /\.modules?\.css$/, namespace: 'file' }, (args) => { | ||
const fullPath = path.resolve(args.resolveDir, args.path); | ||
const tmpCssFile = fullPath.replace(/\.modules?\.css$/, '.modules_tmp_.css'); | ||
fs.writeFileSync(tmpCssFile, '/* placeholder */', { encoding: 'utf-8' }); | ||
outputLogs && console.log('[css-modules-puglin] create a placeholder file on resolve:', tmpCssFile); | ||
return { | ||
path: fullPath, | ||
watchFiles: [fullPath] | ||
}; | ||
}); | ||
let jsContent = _jsContent; | ||
const tmpCss = path.resolve( | ||
sourceDir, | ||
`_tmp_${sourceBaseName}.css`.replace(/\.modules?\./, '.') | ||
); | ||
if (bundle && v2) { | ||
await writeFile(tmpCss, cssContent); | ||
tmpCsses.add(tmpCss); | ||
jsContent = | ||
`import "${tmpCss}"; | ||
` + _jsContent; | ||
} | ||
await writeFile(`${tmpFilePath}.js`, jsContent); | ||
if (outdir && !bundle) { | ||
const isOutdirAbsolute = path.isAbsolute(outdir); | ||
const absoluteOutdir = isOutdirAbsolute ? outdir : path.resolve(args.resolveDir, outdir); | ||
const isEntryAbsolute = path.isAbsolute(args.path); | ||
const entryRelDir = isEntryAbsolute | ||
? path.dirname(path.relative(args.resolveDir, args.path)) | ||
: path.dirname(args.path); | ||
const targetSubpath = | ||
absoluteOutdir.indexOf(entryRelDir) === -1 | ||
? path.join(entryRelDir, `${sourceBaseName}.css.js`) | ||
: `${sourceBaseName}.css.js`; | ||
const target = path.resolve(absoluteOutdir, targetSubpath); | ||
fs.ensureDirSync(path.dirname(target)); | ||
fs.copyFileSync(`${tmpFilePath}.js`, target); | ||
console.log( | ||
'[esbuild-css-modules-plugin]', | ||
path.relative(rootDir, sourceFullPath), | ||
'=>', | ||
path.relative(rootDir, target) | ||
); | ||
} | ||
if (!bundle) { | ||
return { path: sourceFullPath, namespace: 'file' }; | ||
} | ||
return { | ||
path: `${tmpFilePath}.js`, | ||
namespace: pluginNamespace, | ||
pluginData: { | ||
content: jsContent, | ||
resolveArgs: { | ||
path: args.path, | ||
tmpCss, | ||
fullPath: sourceFullPath, | ||
importer: args.importer, | ||
namespace: args.namespace, | ||
resolveDir: args.resolveDir, | ||
kind: args.kind | ||
build.onLoad({ filter: /\.modules?\.css$/, namespace: 'file' }, async (args) => { | ||
const { path: fullPath } = args; | ||
const tmpCssFile = fullPath.replace(/\.modules?\.css$/, '.modules_tmp_.css'); | ||
const { jsContent, cssContent } = await buildCssModulesJS(fullPath, { | ||
...options, | ||
bundle | ||
}); | ||
fs.writeFileSync(tmpCssFile, cssContent, { encoding: 'utf-8' }); | ||
const jsFileContent = `import "${tmpCssFile}";\n${jsContent}`; | ||
tmpFiles.add(tmpCssFile); | ||
return { | ||
contents: jsFileContent, | ||
loader: 'js', | ||
watchFiles: [fullPath] | ||
}; | ||
}); | ||
build.onEnd(() => { | ||
outputLogs && console.log('[css-modules-plugin] Clean temp files...'); | ||
tmpFiles.forEach((f) => { | ||
try { | ||
fs.unlinkSync(f); | ||
} catch (error) {} | ||
}); | ||
}); | ||
} else { | ||
build.onResolve({ filter: /\.modules?\.css$/, namespace: 'file' }, async (args) => { | ||
const sourceFullPath = path.resolve(args.resolveDir, args.path); | ||
const sourceExt = path.extname(sourceFullPath); | ||
const sourceBaseName = path.basename(sourceFullPath, sourceExt); | ||
const sourceDir = path.dirname(sourceFullPath); | ||
const sourceRelDir = path.relative(path.dirname(rootDir), sourceDir); | ||
const tmpDir = path.resolve(tmpDirPath, sourceRelDir); | ||
await ensureDir(tmpDir); | ||
const tmpFilePath = path.resolve(tmpDir, `${sourceBaseName}.css`); | ||
const {jsContent} = await buildCssModulesJS(sourceFullPath, options); | ||
await writeFile(`${tmpFilePath}.js`, jsContent, {encoding: 'utf-8'}); | ||
if (outdir && !bundle) { | ||
const isOutdirAbsolute = path.isAbsolute(outdir); | ||
const absoluteOutdir = isOutdirAbsolute ? outdir : path.resolve(args.resolveDir, outdir); | ||
const isEntryAbsolute = path.isAbsolute(args.path); | ||
const entryRelDir = isEntryAbsolute | ||
? path.dirname(path.relative(args.resolveDir, args.path)) | ||
: path.dirname(args.path); | ||
const targetSubpath = | ||
absoluteOutdir.indexOf(entryRelDir) === -1 | ||
? path.join(entryRelDir, `${sourceBaseName}.css.js`) | ||
: `${sourceBaseName}.css.js`; | ||
const target = path.resolve(absoluteOutdir, targetSubpath); | ||
await ensureDir(path.dirname(target)); | ||
fse.copyFileSync(`${tmpFilePath}.js`, target); | ||
outputLogs && console.log( | ||
'[css-modules-plugin]', | ||
path.relative(rootDir, sourceFullPath), | ||
'=>', | ||
path.relative(rootDir, target) | ||
); | ||
} | ||
if (!bundle) { | ||
return { path: sourceFullPath, namespace: 'file' }; | ||
} | ||
return { | ||
path: `${tmpFilePath}.js`, | ||
namespace: pluginNamespace, | ||
pluginData: { | ||
content: jsContent, | ||
resolveArgs: { | ||
path: args.path, | ||
fullPath: sourceFullPath, | ||
importer: args.importer, | ||
namespace: args.namespace, | ||
resolveDir: args.resolveDir, | ||
kind: args.kind | ||
} | ||
} | ||
} | ||
}; | ||
}); | ||
build.onLoad({ filter: /\.modules?\.css\.js$/, namespace: pluginNamespace }, (args) => { | ||
const { | ||
path: resolvePath, | ||
importer, | ||
fullPath, | ||
resolveDir, | ||
tmpCss | ||
} = args.pluginData.resolveArgs; | ||
const importerName = path.basename(importer); | ||
console.log( | ||
'[esbuild-css-modules-plugin]', | ||
`${resolvePath} => ${resolvePath}.js => ${importerName}` | ||
); | ||
return { | ||
contents: args.pluginData.content, | ||
loader: 'js', | ||
watchFiles: [fullPath], | ||
resolveDir | ||
}; | ||
}); | ||
build.onEnd(() => { | ||
console.log('[esbuild-css-modules-plugin] Clean temp files...'); | ||
tmpCsses.forEach((f) => { | ||
try { | ||
fs.unlinkSync(f); | ||
} catch (error) {} | ||
}; | ||
}); | ||
}); | ||
build.onLoad({ filter: /\.modules?\.css\.js$/, namespace: pluginNamespace }, (args) => { | ||
const { path: resolvePath, importer, fullPath } = args.pluginData.resolveArgs; | ||
const importerName = path.basename(importer); | ||
outputLogs && console.log( | ||
'[css-modules-plugin]', | ||
`${resolvePath} => ${resolvePath}.js => ${importerName}` | ||
); | ||
return { contents: args.pluginData.content, loader: 'js', watchFiles: [fullPath] }; | ||
}); | ||
} | ||
} | ||
@@ -200,0 +202,0 @@ }; |
{ | ||
"name": "esbuild-css-modules-plugin", | ||
"version": "2.0.2", | ||
"version": "2.0.3", | ||
"description": "A esbuild plugin to bundle css modules into js(x)/ts(x).", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
import React from 'react'; | ||
import styles from '../styles/app.modules.css'; | ||
import styles, * as appCssModules from '../styles/app.modules.css'; | ||
export const HelloWorld = () => <> | ||
<h3 className={styles.helloWorld}>Hello World!</h3> | ||
{ | ||
appCssModules.digest && <pre><code>${appCssModules.digest}</code></pre> | ||
} | ||
{ | ||
appCssModules.css && <pre><code>${appCssModules.css}</code></pre> | ||
} | ||
</> |
@@ -21,3 +21,7 @@ const esbuild = require('esbuild'); | ||
}) | ||
] | ||
], | ||
logLevel: 'debug', | ||
loader: { | ||
'.jpg': 'file' | ||
} | ||
}); | ||
@@ -36,3 +40,6 @@ console.log('[test][esbuild:bundle-no-inject] done, please check `test/dist/bundle-no-inject`', '\n'); | ||
plugins: [cssModulesPlugin()], | ||
logLevel: 'debug' | ||
logLevel: 'debug', | ||
loader: { | ||
'.jpg': 'file' | ||
} | ||
}); | ||
@@ -46,3 +53,3 @@ console.log('[test][esbuild:no-bundle] done, please check `test/dist/no-bundle`', '\n'); | ||
bundle: true, | ||
minify: true, | ||
minify: false, | ||
sourcemap: true, | ||
@@ -49,0 +56,0 @@ external: ['react', 'react-dom'], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20805
265
4