-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from thivi/main
chore(react): allow components to be imported through subpath
- Loading branch information
Showing
15 changed files
with
945 additions
and
181 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
dist | ||
.rollup.cache | ||
storybook-static | ||
scripts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
enable-pre-post-scripts=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. 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 path = require('path'); | ||
const fs = require('fs-extra'); | ||
const {execSync} = require('child_process'); | ||
const packageJson = require('../package.json'); | ||
const fixFiles = require('./fix-files'); | ||
const {logger} = require('@oxygen-ui/logger'); | ||
|
||
const outputDir = path.resolve(__dirname, '..', 'dist', 'transpiled'); | ||
|
||
logger.log('💅 Transpiling components...'); | ||
execSync( | ||
`npx tsc --project tsconfig.lib.json --declarationDir ${outputDir} --emitDeclarationOnly false --outDir ${outputDir}`, | ||
); | ||
logger.log('💅 Components transpiled! 🎉🎉🎉'); | ||
|
||
logger.log('💅 Copying components...'); | ||
fs.rmSync(path.resolve(__dirname, '..', 'dist','transpiled','src','components','index.js')); | ||
fs.rmSync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src', 'components', 'index.d.ts')); | ||
fs.copySync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src', 'components', ''), path.resolve(__dirname, '..', 'dist')); | ||
fs.rmdirSync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src', 'components'), {recursive: true}); | ||
fs.rmSync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src', 'index.js')); | ||
fs.rmSync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src', 'index.d.ts')); | ||
fs.copySync(path.resolve(__dirname, '..', 'dist', 'transpiled', 'src'), path.resolve(__dirname, '..', 'dist', '')); | ||
fs.rmdirSync(path.resolve(__dirname, '..', 'dist', 'transpiled'), {recursive: true}); | ||
logger.log('💅 Components copied! 🎉🎉🎉'); | ||
|
||
const packageJsonContent = { | ||
exports: './index.js', | ||
types: './index.d.ts', | ||
}; | ||
|
||
const componentsDir = path.resolve(__dirname, '..', 'src', 'components'); | ||
const componentFiles = fs.readdirSync(componentsDir); | ||
const srcDir = path.resolve(__dirname, '..', 'src'); | ||
const srcFiles = fs.readdirSync(srcDir); | ||
|
||
logger.log('💅 Creating package.json files...'); | ||
componentFiles.forEach(file => { | ||
const componentDir = path.resolve(componentsDir, file); | ||
if (fs.lstatSync(componentDir).isDirectory()) { | ||
fs.writeFileSync(path.resolve(__dirname, '..', 'dist', file, 'package.json'), JSON.stringify(packageJsonContent)); | ||
} | ||
}); | ||
|
||
srcFiles.forEach(file => { | ||
const dir = path.resolve(srcDir, file); | ||
if (fs.lstatSync(dir).isDirectory() && file !== 'components') { | ||
fs.writeFileSync(path.resolve(__dirname, '..', 'dist', file, 'package.json'), JSON.stringify(packageJsonContent)); | ||
} | ||
}); | ||
logger.log('💅 package.json files created! 🎉🎉🎉'); | ||
|
||
logger.log('💅 Creating root package.json file...'); | ||
packageJson.main = './cjs/index.js'; | ||
packageJson.module = './esm/index.js'; | ||
packageJson.types = './index.d.ts'; | ||
fs.writeFileSync(path.resolve(__dirname, '..', 'dist', 'package.json'), JSON.stringify(packageJson)); | ||
logger.log('💅 Root package.json file created! 🎉🎉🎉'); | ||
|
||
logger.log('💅 Fixing the imports in the components and injecting CSS...'); | ||
fixFiles(); | ||
logger.log('💅 Imports fixed and CSS injected into components! 🎉🎉🎉'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. 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 fs = require('fs'); | ||
const path = require('path'); | ||
const saas = require('node-sass'); | ||
const {logger} = require('@oxygen-ui/logger'); | ||
|
||
module.exports = fixFiles = () => { | ||
//All files and directories in the src/components folder. | ||
const componentFiles = fs.readdirSync(path.resolve(__dirname, '..', 'src', 'components')); | ||
|
||
// All directories in the src/components folder. | ||
const componentDirs = componentFiles.filter(file => { | ||
const componentDir = path.resolve(__dirname, '..', 'src', 'components', file); | ||
|
||
return fs.lstatSync(componentDir).isDirectory(); | ||
}); | ||
|
||
// The directories containing the files bundled by Rollup. | ||
const moduleDirs = ['cjs', 'esm']; | ||
|
||
// The non-component directories in the dist folder. | ||
const nonComponentDirsInDist = fs.readdirSync(path.resolve(__dirname, '..', 'dist')).filter(file => { | ||
return ( | ||
!componentDirs.includes(file) && | ||
fs.lstatSync(path.resolve(__dirname, '..', 'dist', file)).isDirectory() && | ||
!moduleDirs.includes(file) | ||
); | ||
}); | ||
|
||
/** | ||
* This method fixes the references to the non-component directories in the dist folder such as utils, constants, etc. | ||
* in imports. | ||
* | ||
* @param {string} file - The file to be fixed. | ||
* @returns {string} - The fixed file. | ||
*/ | ||
const fixImportStatements = file => { | ||
const regExpString = `(import.*from.*[\"|'])(.*(${nonComponentDirsInDist.join('|')}).*)([\"|'].*)`; | ||
const regExp = new RegExp(regExpString, 'g'); | ||
|
||
return file.replace(regExp, (_fullMatch, groupOne, groupTwo, _groupThree, groupFour) => { | ||
return `${groupOne}${groupTwo.replace('../', '')}${groupFour}`; | ||
}); | ||
}; | ||
|
||
/** | ||
* This method updates imports and injects css into component files. | ||
* | ||
* @param {string} filePath - The path to the file to be fixed. | ||
*/ | ||
const fixFiles = filePath => { | ||
fs.readFile(filePath, 'utf8', (err, data) => { | ||
if (err) { | ||
logger.error(err); | ||
|
||
return; | ||
} | ||
|
||
const fixedImports = fixImportStatements(data); | ||
const fixedCSS = loadCSS(fixedImports, filePath); | ||
|
||
fs.writeFile(filePath, fixedCSS, 'utf8', err => { | ||
if (err) { | ||
logger.error(err); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
// The JS code that injects CSS into the head tag. | ||
const codeToInjectCSSIntoHeadTag = | ||
"function addCSS(css){var head = document.getElementsByTagName('head')[ 0 ];" + | ||
"var s = document.createElement('style');s.setAttribute('type', 'text/css');" + | ||
's.appendChild(document.createTextNode(css));head.appendChild(s);}'; | ||
|
||
/** | ||
* This method injects teh `addCSS` function into the file passed as the argument along with the, compiles the | ||
* SASS code of corresponding to the component into CSS, and calls the `addCSS` method with the CSS code as the | ||
* argument. | ||
* | ||
* @param {string} file - The file to be injected with the `addCSS` function. | ||
* @param {string} filePath - The path to the file. | ||
* @returns {string} file - The file with the `addCSS` function injected. | ||
*/ | ||
const loadCSS = (file, filePath) => { | ||
const componentDir = filePath.split(path.sep).slice(-2)[0]; | ||
let css = ''; | ||
|
||
file.match(/['|"].*\.scss["|']/g)?.forEach(match => { | ||
const sassFilePath = path.resolve(__dirname, '..', 'src', 'components', componentDir, match.replace(/['|"]/g, '')); | ||
css += saas.renderSync({file: sassFilePath}).css.toString(); | ||
}); | ||
|
||
file = file.replace(/import.*['|"].*\.scss["|'].*/g, ''); | ||
|
||
if (css === '' || path.extname(filePath) === '.ts') { | ||
return file; | ||
} | ||
|
||
file += `${codeToInjectCSSIntoHeadTag}\naddCSS(\'${JSON.stringify(css)}\');`; | ||
|
||
return file; | ||
}; | ||
|
||
/** | ||
* Traverses through the directories and fixes imports and injects CSS. | ||
* | ||
* @param {string} directory - The directory to be parsed. | ||
*/ | ||
parseComponents = (directory) => { | ||
fs.readdirSync(directory).forEach(file => { | ||
const absolutePath = path.resolve(directory, file); | ||
if (![...nonComponentDirsInDist, ...moduleDirs].includes(file)) { | ||
if (fs.statSync(absolutePath).isDirectory()) { | ||
parseComponents(absolutePath); | ||
} else { | ||
if ( | ||
(file.endsWith('.js') || file.endsWith('.ts')) && | ||
componentDirs.includes(directory.split(path.sep).slice(-1)[0]) | ||
) { | ||
fixFiles(absolutePath); | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
|
||
parseComponents(path.resolve(__dirname, '..', 'dist')); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.