Skip to content

Commit

Permalink
Emit a deprecation warning when loaded as a default export (#230)
Browse files Browse the repository at this point in the history
See #229
  • Loading branch information
nex3 authored Jun 13, 2023
1 parent 4e12a1a commit ad48f1c
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 6 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
check-latest: true
- uses: frenck/action-setup-yq@v1
with: {version: v4.30.5} # frenck/action-setup-yq#35
- uses: dart-lang/setup-dart@v1
with: {sdk: stable}
- run: dart --version
Expand All @@ -72,6 +70,8 @@ jobs:
npm run init -- --compiler-path=dart-sass --language-path=language $args
- run: npm run test
- run: npm run compile
- run: node test/after-compile-test.mjs

# The versions should be kept up-to-date with the latest LTS Node releases.
# They next need to be rotated October 2021. See
Expand All @@ -98,8 +98,6 @@ jobs:
with: {sdk: stable}
- uses: actions/setup-node@v2
with: {node-version: "${{ matrix.node_version }}"}
- uses: frenck/action-setup-yq@v1
with: {version: v4.30.5} # frenck/action-setup-yq#35

- name: Check out Dart Sass
uses: sass/clone-linked-repo@v1
Expand Down
154 changes: 154 additions & 0 deletions lib/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import * as sass from './index.js';

export const compile = sass.compile;
export const compileAsync = sass.compileAsync;
export const compileString = sass.compileString;
export const compileStringAsync = sass.compileStringAsync;
export const Logger = sass.Logger;
export const SassArgumentList = sass.SassArgumentList;
export const SassBoolean = sass.SassBoolean;
export const SassColor = sass.SassColor;
export const SassFunction = sass.SassFunction;
export const SassList = sass.SassList;
export const SassMap = sass.SassMap;
export const SassNumber = sass.SassNumber;
export const SassString = sass.SassString;
export const Value = sass.Value;
export const CustomFunction = sass.CustomFunction;
export const ListSeparator = sass.ListSeparator;
export const sassFalse = sass.sassFalse;
export const sassNull = sass.sassNull;
export const sassTrue = sass.sassTrue;
export const Exception = sass.Exception;
export const PromiseOr = sass.PromiseOr;
export const info = sass.info;
export const render = sass.render;
export const renderSync = sass.renderSync;
export const TRUE = sass.TRUE;
export const FALSE = sass.FALSE;
export const NULL = sass.NULL;
export const types = sass.types;

let printedDefaultExportDeprecation = false;
function defaultExportDeprecation() {
if (printedDefaultExportDeprecation) return;
printedDefaultExportDeprecation = true;
console.error(
"`import sass from 'sass'` is deprecated.\n" +
"Please use `import * as sass from 'sass'` instead.");
}

export default {
get compile() {
defaultExportDeprecation();
return sass.compile;
},
get compileAsync() {
defaultExportDeprecation();
return sass.compileAsync;
},
get compileString() {
defaultExportDeprecation();
return sass.compileString;
},
get compileStringAsync() {
defaultExportDeprecation();
return sass.compileStringAsync;
},
get Logger() {
defaultExportDeprecation();
return sass.Logger;
},
get SassArgumentList() {
defaultExportDeprecation();
return sass.SassArgumentList;
},
get SassBoolean() {
defaultExportDeprecation();
return sass.SassBoolean;
},
get SassColor() {
defaultExportDeprecation();
return sass.SassColor;
},
get SassFunction() {
defaultExportDeprecation();
return sass.SassFunction;
},
get SassList() {
defaultExportDeprecation();
return sass.SassList;
},
get SassMap() {
defaultExportDeprecation();
return sass.SassMap;
},
get SassNumber() {
defaultExportDeprecation();
return sass.SassNumber;
},
get SassString() {
defaultExportDeprecation();
return sass.SassString;
},
get Value() {
defaultExportDeprecation();
return sass.Value;
},
get CustomFunction() {
defaultExportDeprecation();
return sass.CustomFunction;
},
get ListSeparator() {
defaultExportDeprecation();
return sass.ListSeparator;
},
get sassFalse() {
defaultExportDeprecation();
return sass.sassFalse;
},
get sassNull() {
defaultExportDeprecation();
return sass.sassNull;
},
get sassTrue() {
defaultExportDeprecation();
return sass.sassTrue;
},
get Exception() {
defaultExportDeprecation();
return sass.Exception;
},
get PromiseOr() {
defaultExportDeprecation();
return sass.PromiseOr;
},
get info() {
defaultExportDeprecation();
return sass.info;
},
get render() {
defaultExportDeprecation();
return sass.render;
},
get renderSync() {
defaultExportDeprecation();
return sass.renderSync;
},
get TRUE() {
defaultExportDeprecation();
return sass.TRUE;
},
get FALSE() {
defaultExportDeprecation();
return sass.FALSE;
},
get NULL() {
defaultExportDeprecation();
return sass.NULL;
},
get types() {
defaultExportDeprecation();
return sass.types;
},
};
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"repository": "sass/embedded-host-node",
"author": "Google Inc.",
"license": "MIT",
"exports": {
"import": "dist/lib/index.mjs",
"default": "dist/lib/index.js"
},
"main": "dist/lib/index.js",
"types": "dist/types/index.d.ts",
"files": [
Expand All @@ -21,7 +25,7 @@
"check:gts": "gts check",
"check:tsc": "tsc --noEmit",
"clean": "gts clean",
"compile": "tsc",
"compile": "tsc && cp lib/index.mjs dist/lib/index.mjs",
"fix": "gts fix",
"prepublishOnly": "npm run clean && ts-node ./tool/prepare-release.ts",
"test": "jest"
Expand Down
33 changes: 33 additions & 0 deletions test/after-compile-test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2023 Google LLC. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import * as fs from 'fs';

// Note: this file isn't .test.ts specifically because we _don't_ want Jest to
// handle it, because Jest chokes on dynamic imports of literal ESM modules.

// This file should only be run _after_ `npm run compile`.
if (!fs.existsSync('dist/package.json')) {
throw new Error('after-compile.test.ts must be run after `npm run compile`.');
}

// Load these dynamically so we have a better error mesage if `npm run compile`
// hasn't been run.
const cjs = await import('../dist/lib/index.js');
const esm = await import('../dist/lib/index.mjs');

for (const [name, value] of Object.entries(cjs)) {
if (name === '__esModule' || name === 'default') continue;
if (!esm[name]) {
throw new Error(`ESM module is missing export ${name}.`);
} else if (esm[name] !== value) {
throw new Error(`ESM ${name} isn't the same as CJS.`);
}

if (!esm.default[name]) {
throw new Error(`ESM default export is missing export ${name}.`);
} else if (esm.default[name] !== value) {
throw new Error(`ESM default export ${name} isn't the same as CJS.`);
}
}
1 change: 0 additions & 1 deletion test/dependencies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import * as child_process from 'child_process';
import * as fs from 'fs';
import * as p from 'path';

Expand Down
1 change: 1 addition & 0 deletions tool/prepare-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {getLanguageRepo} from './get-language-repo';

console.log('Transpiling TS into dist.');
shell.exec('tsc');
shell.cp('lib/index.mjs', 'dist/lib/index.mjs');

console.log('Copying JS API types to dist.');
shell.cp('-R', 'lib/src/vendor/sass', 'dist/types');
Expand Down

0 comments on commit ad48f1c

Please sign in to comment.