diff --git a/src/insertStyle.ts b/src/insertStyle.ts index 1814aa0..d8edf9d 100644 --- a/src/insertStyle.ts +++ b/src/insertStyle.ts @@ -10,9 +10,7 @@ export default function insertStyle( css: string | undefined, ): string | undefined { - if (!css || typeof window === 'undefined') { - return; - } + if (!css || typeof window === 'undefined') return; const style = document.createElement('style'); style.setAttribute('type', 'text/css'); diff --git a/src/types.ts b/src/types.ts index 2acba2e..cbc3f49 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,7 +19,7 @@ export type RollupPluginSassProcessorFnOutput = css: string; /** If provided, the default export of the CSS file will be the map returned here */ - cssModules?: Record, + cssModules?: Record; // User processor might add additional exports [key: string]: unknown; diff --git a/test/index.test.ts b/test/index.test.ts index 146bcaa..b7afc8e 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -20,6 +20,7 @@ import sass from '../src/index'; import type { RollupPluginSassOutputFn, RollupPluginSassOptions, + RollupPluginSassProcessorFn, } from '../src/types'; type ApiValue = Extract; @@ -260,7 +261,7 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( }, }); } -// #endregion +// #endregion basic tests // #region insert option { @@ -397,7 +398,7 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); } -// #endregion +// #endregion insert option // #region output option { @@ -425,7 +426,6 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( * Right now we can't use snapshot testing on this tests because sometimes rollup mess with the order of imports. * Detailed information can be found here: https://github.com/elycruz/rollup-plugin-sass/pull/143#issuecomment-2227274405 */ - { const title = 'should support output as function'; @@ -713,47 +713,133 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); } -// { -// const title = -// 'should produces CSS modules if `cssModules` is returned from processor'; - -// const macro = test.macro<[RollupPluginSassOptions]>({ -// async exec(t, pluginOptions) { -// const outputBundle = await rollup({ -// input: 'test/fixtures/css-modules/index.js', -// plugins: [ -// sass({ -// ...pluginOptions, -// processor: async (styles, id) => { -// let cssModules = {}; -// const postcssProcessResult = await postcss([ -// postcssModules({ -// getJSON: (_, json) => { -// if (json) cssModules = json; -// }, -// }), -// ]).process(styles, { -// from: id, -// }); - -// return { css: postcssProcessResult.css, cssModules }; -// }, -// }), -// ], -// }); - -// const { output } = await outputBundle.generate(TEST_GENERATE_OPTIONS); -// const result = getFirstChunkCode(output); - -// t.snapshot(result); -// }, -// title: createApiOptionTestCaseTitle, -// }); - -// test.only(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); -// test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); -// } -// #endregion +{ + const postcssModulesProcessor: RollupPluginSassProcessorFn = async ( + styles, + id, + ) => { + let cssModules = {}; + const postcssProcessResult = await postcss([ + postcssModules({ + getJSON: (_, json) => { + if (json) cssModules = json; + }, + }), + ]).process(styles, { + from: id, + }); + + return { css: postcssProcessResult.css, cssModules }; + }; + + { + const title = + 'should produces CSS modules if `cssModules` is returned from processor'; + + const macro = test.macro<[RollupPluginSassOptions]>({ + async exec(t, pluginOptions) { + const outputBundle = await rollup({ + input: 'test/fixtures/css-modules/index.js', + plugins: [ + sass({ + ...pluginOptions, + processor: postcssModulesProcessor, + }), + ], + }); + + const { output } = await outputBundle.generate(TEST_GENERATE_OPTIONS); + const result = getFirstChunkCode(output); + + t.snapshot(result); + }, + title: createApiOptionTestCaseTitle, + }); + + test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); + test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); + } + + // { + // const title = + // 'should produces CSS modules alongside `insertStyle` if `cssModules` is returned from processor'; + + // const macro = test.macro<[RollupPluginSassOptions]>({ + // async exec(t, pluginOptions) { + // const outputBundle = await rollup({ + // input: 'test/fixtures/css-modules/index.js', + // plugins: [ + // sass({ + // ...pluginOptions, + // insert: true, + // processor: postcssModulesProcessor, + // }), + // ], + // }); + + // const { output } = await outputBundle.generate(TEST_GENERATE_OPTIONS); + + // t.is( + // output.length, + // 1, + // 'has 1 chunk (we are bundling all in one single file)', + // ); + + // const [{ moduleIds, modules }] = output; + + // t.is( + // moduleIds.filter((it) => it.endsWith('insertStyle')).length, + // 1, + // 'include insertStyle one time', + // ); + + // const actualAModuleID = moduleIds.find((it) => + // it.endsWith('actual_a.scss'), + // ) as string; + // const actualAModule = modules[actualAModuleID]; + // t.truthy(actualAModule); + // t.snapshot( + // actualAModule.code, + // 'actual_a content is compiled with insertStyle', + // ); + // }, + // title: createApiOptionTestCaseTitle, + // }); + + // test.only(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); + // test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); + // } + + { + const title = 'should throw error when CSS modules is not an object'; + + const macro = test.macro<[RollupPluginSassOptions]>({ + async exec(t, pluginOptions) { + const message = + 'You need to provide a js object as `cssModules` property. See https://github.com/elycruz/rollup-plugin-sass#processor'; + + await t.throwsAsync( + rollup({ + input: 'test/fixtures/css-modules/index.js', + plugins: [ + sass({ + ...pluginOptions, + // @ts-expect-error testing error + processor: () => ({ css: 'body {}', cssModules: 'asd' }), + }), + ], + }), + { message }, + ); + }, + title: createApiOptionTestCaseTitle, + }); + + test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); + test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); + } +} +// #endregion processor option // #region node resolution { @@ -833,7 +919,7 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); } -// #endregion +// #endregion node resolution { const title = 'should support options.runtime'; @@ -960,7 +1046,7 @@ const createApiOptionTestCaseTitle: TitleFn<[RollupPluginSassOptions]> = ( test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_LEGACY); test(title, macro, TEST_PLUGIN_OPTIONS_DEFAULT_MODERN); } -// #endregion +// #endregion sourcemap { const title = 'module stylesheets graph should be added to watch list'; diff --git a/test/snapshots/test/index.test.ts.md b/test/snapshots/test/index.test.ts.md index f294f4f..b943d4b 100644 --- a/test/snapshots/test/index.test.ts.md +++ b/test/snapshots/test/index.test.ts.md @@ -250,6 +250,24 @@ Generated by [AVA](https://avajs.dev). export { color, color2, withIcssExports as default };␊ ` +## should produces CSS modules if `cssModules` is returned from processor using 'api' = 'legacy' (implicit) + +> Snapshot 1 + + `var style = {"something":"_something_ngy8h_1"};␊ + ␊ + export { style as default };␊ + ` + +## should produces CSS modules if `cssModules` is returned from processor using 'api' = 'modern' + +> Snapshot 1 + + `var style = {"something":"_something_ngy8h_1"};␊ + ␊ + export { style as default };␊ + ` + ## should resolve ~ as node_modules using 'api' = 'legacy' (implicit) > Snapshot 1 diff --git a/test/snapshots/test/index.test.ts.snap b/test/snapshots/test/index.test.ts.snap index 18706b3..2fc71e8 100644 Binary files a/test/snapshots/test/index.test.ts.snap and b/test/snapshots/test/index.test.ts.snap differ