From 0d9b5b422a9e18cc6391fa119abe41b7d384c154 Mon Sep 17 00:00:00 2001 From: Nickolas Oliver Date: Mon, 12 Jun 2023 10:21:48 -0700 Subject: [PATCH] fix(one-app-dev-bundler): avoid default export of sass accidentally removed in 1.63.0 through 1.63.3, will be removed in 2.x https://github.com/sass/dart-sass/issues/2008 --- .../esbuild/plugins/styles-loader.spec.js | 35 ++++++++++++------- .../esbuild/plugins/styles-loader.js | 4 +-- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/one-app-dev-bundler/__tests__/esbuild/plugins/styles-loader.spec.js b/packages/one-app-dev-bundler/__tests__/esbuild/plugins/styles-loader.spec.js index 3b90bb41..1c893611 100644 --- a/packages/one-app-dev-bundler/__tests__/esbuild/plugins/styles-loader.spec.js +++ b/packages/one-app-dev-bundler/__tests__/esbuild/plugins/styles-loader.spec.js @@ -15,7 +15,7 @@ */ import glob from 'glob-all'; -import sass from 'sass'; +import { compile as sassCompile } from 'sass'; import stylesLoader from '../../../esbuild/plugins/styles-loader'; import { runSetupAndGetLifeHooks, runOnLoadHook } from './__plugin-testing-utils__'; import { @@ -29,7 +29,16 @@ jest.mock('glob-all'); jest.mock('cssnano'); -jest.spyOn(sass, 'compile'); +// sass has different loaders for CJS and ESM, the latter does not have a "default" export +// making `import sass from 'sass';` throw an error +// Jest is still working on ESM mocking https://jestjs.io/docs/ecmascript-modules#module-mocking-in-esm +// so there is a divergance from this test setup and sass versions: update this setup once the jest +// API is stable +jest.mock('sass', () => { + const sass = jest.requireActual('sass'); + jest.spyOn(sass, 'compile'); + return sass; +}); const mockNodeEnv = (env) => { let oldEnv; @@ -93,8 +102,8 @@ describe('Esbuild plugin stylesLoader', () => { { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(1); - expect(sass.compile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); + expect(sassCompile).toHaveBeenCalledTimes(1); + expect(sassCompile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` @@ -140,7 +149,7 @@ body > p { { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(0); + expect(sassCompile).toHaveBeenCalledTimes(0); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` "const digest = '83279c4025e8b1107c3f376acaaac5656a3b68d0066ab70f2ceeb3c065a5751f'; @@ -186,8 +195,8 @@ body > p { { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(1); - expect(sass.compile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); + expect(sassCompile).toHaveBeenCalledTimes(1); + expect(sassCompile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` @@ -227,7 +236,7 @@ body > p { { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(0); + expect(sassCompile).toHaveBeenCalledTimes(0); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` "const digest = '83279c4025e8b1107c3f376acaaac5656a3b68d0066ab70f2ceeb3c065a5751f'; @@ -294,7 +303,7 @@ export { css, digest };" additionalMockedFiles ); - expect(sass.compile).toHaveBeenCalledTimes(0); + expect(sassCompile).toHaveBeenCalledTimes(0); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` "const digest = '786f696ae19422021e0f17df7c6dd6eb43f92c9c101f7d0649b341165dda1b31'; @@ -366,7 +375,7 @@ export { css, digest };" additionalMockedFiles ); - expect(sass.compile).toHaveBeenCalledTimes(0); + expect(sassCompile).toHaveBeenCalledTimes(0); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` "const digest = '786f696ae19422021e0f17df7c6dd6eb43f92c9c101f7d0649b341165dda1b31'; @@ -418,8 +427,8 @@ export { css, digest };" { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(1); - expect(sass.compile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); + expect(sassCompile).toHaveBeenCalledTimes(1); + expect(sassCompile).toHaveBeenCalledWith(`mock/path/to/file/${mockFileName}`, { loadPaths: ['./node_modules'] }); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` @@ -469,7 +478,7 @@ body > p { { mockFileName, mockFileContent } ); - expect(sass.compile).toHaveBeenCalledTimes(0); + expect(sassCompile).toHaveBeenCalledTimes(0); expect(loader).toEqual('js'); expect(contents).toMatchInlineSnapshot(` "const digest = '83279c4025e8b1107c3f376acaaac5656a3b68d0066ab70f2ceeb3c065a5751f'; diff --git a/packages/one-app-dev-bundler/esbuild/plugins/styles-loader.js b/packages/one-app-dev-bundler/esbuild/plugins/styles-loader.js index 8941072f..c04d5f8b 100644 --- a/packages/one-app-dev-bundler/esbuild/plugins/styles-loader.js +++ b/packages/one-app-dev-bundler/esbuild/plugins/styles-loader.js @@ -14,7 +14,7 @@ * permissions and limitations under the License. */ -import sass from 'sass'; +import { compile as sassCompile } from 'sass'; import postcss from 'postcss'; import cssModules from 'postcss-modules'; import crypto from 'crypto'; @@ -40,7 +40,7 @@ const stylesLoader = (cssModulesOptions = {}, { bundleType } = {}) => ({ // Compile scss to css let cssContent; if (args.path.endsWith('scss')) { - cssContent = sass.compile(args.path, { loadPaths: ['./node_modules'] }).css.toString(); + cssContent = sassCompile(args.path, { loadPaths: ['./node_modules'] }).css.toString(); } else { cssContent = await fs.promises.readFile(args.path, 'utf8'); }