Skip to content

Commit

Permalink
Replace node-sass with sass-embedded
Browse files Browse the repository at this point in the history
Also:
* Implement sass variable extraction
* Implement sass variable importing in typescript
* Add guards to post-install cleanup
* Make sources compatible with dart sass by wrapping divisions in `calc()` and adding units were necessary
* Fold in `@elastic/charts/dist/theme.scss` to modify it for dart-sass compatibility
* Break out compiling `charts`

Signed-off-by: Miki <miki@amazon.com>
  • Loading branch information
AMoo-Miki committed Aug 30, 2023
1 parent 53ad3e7 commit 7f81d1b
Show file tree
Hide file tree
Showing 100 changed files with 1,183 additions and 618 deletions.
1 change: 1 addition & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = {
"@babel/plugin-syntax-dynamic-import",
"pegjs-inline-precompile",
"./scripts/babel/proptypes-from-ts-props",
"./scripts/babel/variables-from-scss",
"add-module-exports",
// stage 3
"@babel/proposal-object-rest-spread",
Expand Down
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# force unix-style LF (\n) line endings for source files
# this is necessary for prettier's linting and sass-vars-to-js-loader
# this is necessary for prettier's linting
*.js text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
Expand Down
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ test/failure-screenshots/**/*.png
coverage/
reports/
tmp/
dist/
docs/
lib/
/dist/
/docs/
/lib/
es/
test-env/
.idea
Expand Down
2 changes: 2 additions & 0 deletions .sass-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ rules:
space-around-operator: 2
# We minify css, so this doesn't apply
no-css-comments: 0
# sass wants units
zero-unit: 0
# We use _ (underscores) for import path that don't directly compile
clean-import-paths: 0
# Allows input[type=search]
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
- [CVE-2023-26115] Bump word-wrap from 1.2.3 to 1.2.4 ([#891](https://github.com/opensearch-project/oui/pull/891))
- Bump Node version to 18.16.0 ([#900](https://github.com/opensearch-project/oui/pull/900))
- Bump `node-sass` to a patched version based on `libsass@3.6.5` ([#977](https://github.com/opensearch-project/oui/pull/977)); see [patch commit](https://github.com/AMoo-Miki/node-sass/commit/43c74c0966b05c1e21a1e5e20a0c467ec8e669b4) for details.
- Replace `node-sass` with `sass-embedded` ([#1001](https://github.com/opensearch-project/oui/pull/1001))

### 🪛 Refactoring

Expand Down
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"test-docker": "node ./scripts/test-docker.js",
"sync-docs": "node ./scripts/docs-sync.js",
"build-docs": "cross-env BABEL_MODULES=false cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 webpack --config=src-docs/webpack.config.js",
"build": "yarn extract-i18n-strings && node ./scripts/compile-clean.js && node ./scripts/compile-oui.js && node ./scripts/compile-scss.js $npm_package_name",
"build": "yarn extract-i18n-strings && node ./scripts/compile-clean.js && node ./scripts/compile-oui.js && node ./scripts/compile-themes.js $npm_package_name && node ./scripts/compile-charts.js",
"clean": "node ./scripts/compile-clean.js",
"compile-icons": "node ./scripts/compile-icons.js && prettier --write --loglevel=warn \"./src/components/icon/assets/**/*.js\"",
"extract-i18n-strings": "node ./scripts/babel/fetch-i18n-strings",
Expand Down Expand Up @@ -67,7 +67,6 @@
"jest-cli/**/tough-cookie": "^4.1.3",
"jest/**/node-notifier": "^10.0.1",
"jest/**/tough-cookie": "^4.1.3",
"node-sass/sass-graph/scss-tokenizer": "^0.4.3",
"postcss-cli/chokidar/glob-parent": "^6.0.1",
"postcss-inline-svg/css-select/nth-check": "^2.0.1",
"react-view/**/ansi-regex": "^5.0.1",
Expand Down Expand Up @@ -214,7 +213,6 @@
"jest-cli": "^24.1.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.41",
"node-sass": "npm:@amoo-miki/node-sass@9.0.0-libsass-3.6.5",
"pegjs": "^0.10.0",
"postcss-cli": "^7.1.2",
"postcss-inline-svg": "^4.1.0",
Expand All @@ -236,11 +234,10 @@
"redux-thunk": "^2.4.2",
"resolve": "^1.22.1",
"rimraf": "^5.0.1",
"sass-extract": "^2.1.0",
"sass-embedded": "^1.66.1",
"sass-lint": "^1.13.1",
"sass-lint-auto-fix": "^0.21.2",
"sass-loader": "npm:@bsfishy/sass-loader@node-sass-9",
"sass-vars-to-js-loader": "^2.1.1",
"sass-loader": "npm:@bsfishy/sass-loader@10.4.1-support-sass-embedded.3",
"shelljs": "^0.8.5",
"start-server-and-test": "^2.0.0",
"style-loader": "^1.2.1",
Expand Down
40 changes: 40 additions & 0 deletions scripts/babel/variables-from-scss/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const fs = require('fs');
const { join, dirname, parse } = require('path');
const { compileWithVariablesSync } = require('../../lib/compile-scss-with-variables');

const idKey = '!!variables-from-scss!!';
const keyLength = idKey.length;

const forbiddenKeyNames = [...Object.getOwnPropertyNames(Object.prototype), 'prototype'];

module.exports = (babel) => ({
visitor: {
ImportDeclaration(path, state) {
if (path.node.source.value.startsWith(idKey)) {
const deconstructedAssignments = [];
const usedVariableNames = [];
const assignments = [];
for (const specifier of path.node.specifiers) {
if (specifier.type === 'ImportDefaultSpecifier') {
assignments.push(specifier.local.name);
} else if (specifier.type === 'ImportSpecifier') {
usedVariableNames.push(specifier.imported.name);
deconstructedAssignments.push(specifier.imported.name === specifier.local.name ? specifier.local.name : `${specifier.imported.name}: ${specifier.local.name}`);
}
}

const importTarget = join(dirname(state.file.opts.filename), path.node.source.value.substring(keyLength));
const { variables } = compileWithVariablesSync(importTarget);

// If no default specifier is used, reduce the variables to only those needed
const importedVariables = assignments.length === 0 ? usedVariableNames.reduce((acc, name) => {
if (!forbiddenKeyNames.includes(name)) acc[name] = variables[name];
return acc;
}, {}) : variables;

if (deconstructedAssignments.length > 0) assignments.push(`{ ${deconstructedAssignments.join(', ')} }`);
path.replaceWith(babel.template.statement.ast(`const ${assignments.join(', ')} = ${JSON.stringify(importedVariables)};`));
}
}
}
});
88 changes: 88 additions & 0 deletions scripts/compile-charts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/


const { execSync } = require('child_process');
const chalk = require('chalk');
const path = require('path');
const dtsGenerator = require('dts-generator').default;

function compileChartsBundle() {
console.log('Building chart theme module...');
execSync(
'webpack src/themes/charts/themes.ts -o dist/oui_charts_theme.js --output-library-target="commonjs" --config=src/webpack.config.js',
{
stdio: 'inherit',
}
);
dtsGenerator({
prefix: '',
out: 'dist/oui_charts_theme.d.ts',
baseDir: path.resolve(__dirname, '..', 'src/themes/charts/'),
files: ['themes.ts'],
resolveModuleId() {
return '@opensearch-project/oui/dist/oui_charts_theme';
},
resolveModuleImport(params) {
if (params.importedModuleId === '../../components/common') {
return '@opensearch-project/oui/src/components/common';
}
return null;
}
});

/* OUI -> EUI Aliases */
execSync(
'webpack src/themes/charts/themes.ts -o dist/eui_charts_theme.js --output-library-target="commonjs" --config=src/webpack.config.js',
{
stdio: 'inherit',
}
);
dtsGenerator({
prefix: '',
out: 'dist/eui_charts_theme.d.ts',
baseDir: path.resolve(__dirname, '..', 'src/themes/charts/'),
files: ['themes.ts'],
resolveModuleId() {
return '@elastic/eui/dist/eui_charts_theme';
},
resolveModuleImport(params) {
if (params.importedModuleId === '../../components/common') {
return '@elastic/eui/src/components/common';
}
return null;
}
});
/* End of Aliases */

console.log(chalk.green('✔ Finished chart theme module'));
}

compileChartsBundle();
49 changes: 0 additions & 49 deletions scripts/compile-oui.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,55 +308,6 @@ function compileBundle() {
}
});
console.log(chalk.green('✔ Finished test utils files'));

console.log('Building chart theme module...');
execSync(
'webpack src/themes/charts/themes.ts -o dist/oui_charts_theme.js --output-library-target="commonjs" --config=src/webpack.config.js',
{
stdio: 'inherit',
}
);
dtsGenerator({
prefix: '',
out: 'dist/oui_charts_theme.d.ts',
baseDir: path.resolve(__dirname, '..', 'src/themes/charts/'),
files: ['themes.ts'],
resolveModuleId() {
return '@opensearch-project/oui/dist/oui_charts_theme';
},
resolveModuleImport(params) {
if (params.importedModuleId === '../../components/common') {
return '@opensearch-project/oui/src/components/common';
}
return null;
}
});

/* OUI -> EUI Aliases */
execSync(
'webpack src/themes/charts/themes.ts -o dist/eui_charts_theme.js --output-library-target="commonjs" --config=src/webpack.config.js',
{
stdio: 'inherit',
}
);
dtsGenerator({
prefix: '',
out: 'dist/eui_charts_theme.d.ts',
baseDir: path.resolve(__dirname, '..', 'src/themes/charts/'),
files: ['themes.ts'],
resolveModuleId() {
return '@elastic/eui/dist/eui_charts_theme';
},
resolveModuleImport(params) {
if (params.importedModuleId === '../../components/common') {
return '@elastic/eui/src/components/common';
}
return null;
}
});
/* End of Aliases */

console.log(chalk.green('✔ Finished chart theme module'));
}

/* OUI -> EUI Aliases */
Expand Down
23 changes: 7 additions & 16 deletions scripts/compile-scss.js → scripts/compile-themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,17 @@

const path = require('path');
const util = require('util');
const fs = require('fs');
const { writeFile, mkdir, readFile } = require('fs/promises');
const globModule = require('glob');

const chalk = require('chalk');
const postcss = require('postcss');
const sassExtract = require('sass-extract');
const { deriveSassVariableTypes } = require('./derive-sass-variable-types');
const sassExtractJsPlugin = require('./sass-extract-js-plugin');

const { compileWithVariables } = require('./lib/compile-scss-with-variables');
const { deriveSassVariableTypes } = require('./lib/derive-sass-variable-types');

const postcssConfiguration = require('../postcss.config.js');

const writeFile = util.promisify(fs.writeFile);
const mkdir = util.promisify(fs.mkdir);
const glob = util.promisify(globModule);

const postcssConfigurationWithMinification = {
Expand Down Expand Up @@ -120,15 +118,7 @@ async function compileScssFile(
'.min.css'
);

const { css: renderedCss, vars: extractedVars } = await sassExtract.render(
{
file: inputFilename,
outFile: outputCssFilename,
},
{
plugins: [sassExtractJsPlugin],
}
);
const { css: renderedCss, variables: extractedVars } = await compileWithVariables(path.resolve(inputFilename));

/* OUI -> EUI Aliases: Modified */
// const extractedVarTypes = await deriveSassVariableTypes(
Expand Down Expand Up @@ -203,5 +193,6 @@ if (require.main === module) {
process.exit(1);
}

compileScssFiles(path.join('src', 'theme_*.scss'), 'dist', ouiPackageName);
compileScssFiles(path.join('src', 'theme_*.scss'), 'dist', ouiPackageName)
.catch(console.error);
}
Loading

0 comments on commit 7f81d1b

Please sign in to comment.