Skip to content
Permalink
Browse files

feat(core): a core bundle (#138)

* feat(core): add paste core package

* chore: update yarn.lock

* chore: use writeToFile in other scripts

* fix(core): uncomment terser plugin

* chore: minor fixes

* fix: logic error that allowed typography to be bundled prematurely
  • Loading branch information
TheSisb committed Oct 24, 2019
1 parent 70d4c15 commit f6ab2eb924c29235d6889fb55960c788b96fdf01
@@ -32,7 +32,7 @@
"@twilio-paste/text": "^0.4.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"styled-system": "^4.1.0"
"styled-system": "^5.1.2"
},
"devDependencies": {
"@twilio-paste/text": "^0.4.1",
@@ -0,0 +1,19 @@
# @twilio-paste/core

One bundle containing every package within paste-core.

## How it works

### Procedure (happens in pre-build; see tools/generate.js)

1- Use lerna to fetch all the packages (see /tools/.cache/packages.json).
2- Filter out all packages that aren't productionized or not in core

(For the remaining packages:)

1- Add them to this package's dependencies.
2- Add the export lines to the index.tsx file.

### When this procedure is triggered

This happens automatically during prebuild.
@@ -0,0 +1,56 @@
{
"name": "@twilio-paste/core",
"version": "0.0.1",
"status": "beta",
"description": "Contains all the core packages from the Paste internal design system.",
"author": "Twilio Inc.",
"license": "MIT",
"main:dev": "src/index.tsx",
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"files": [
"dist"
],
"scripts": {
"prebuild": "node ./tools/generate.js",
"build": "yarn clean && yarn compile",
"build:dev": "yarn clean && yarn compile:dev",
"clean": "rm -rf ./dist && rm -rf tsconfig.build.tsbuildinfo && rm -rf .rpt2_cache",
"compile": "rollup -c --environment NODE_ENV:production",
"compile:dev": "rollup -cw --environment NODE_ENV:development",
"prepublishOnly": "yarn build",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@twilio-paste/anchor": "^0.1.5",
"@twilio-paste/button": "^0.2.1",
"@twilio-paste/heading": "^0.3.4",
"@twilio-paste/spinner": "^0.1.6",
"@twilio-paste/absolute": "^0.2.0",
"@twilio-paste/aspect-ratio": "^0.1.1",
"@twilio-paste/box": "^0.3.1",
"@twilio-paste/media-object": "^0.3.1",
"@twilio-paste/screen-reader-only": "^0.2.0",
"@twilio-paste/text": "^0.4.1",
"@twilio-paste/truncate": "^0.1.4"
},
"peerDependencies": {
"@emotion/core": "^10.0.10",
"@emotion/styled": "^10.0.10",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-uid": "^2.2.0",
"styled-system": "^5.1.2"
},
"devDependencies": {
"rollup": "^1.16.2",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-node-resolve": "^5.1.0",
"rollup-plugin-terser": "^5.0.0",
"rollup-plugin-typescript2": "^0.21.2",
"typescript": "^3.5.2"
}
}
@@ -0,0 +1,34 @@
import typescript from 'rollup-plugin-typescript2';
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import {terser} from 'rollup-plugin-terser';
import pkg from './package.json';

export default {
input: pkg['main:dev'],
output: [
{
file: pkg.main,
format: 'cjs',
},
{
file: pkg.module,
format: 'es',
},
],
external: [...Object.keys(pkg.peerDependencies || {})],
plugins: [
resolve(),
commonjs(),
typescript({
clean: true,
typescript: require('typescript'),
tsconfig: './tsconfig.build.json',
}),
babel({
exclude: 'node_modules/**',
}),
process.env.NODE_ENV === 'production' ? terser() : null,
],
};
@@ -0,0 +1,11 @@
export * from '@twilio-paste/anchor';
export * from '@twilio-paste/button';
export * from '@twilio-paste/heading';
export * from '@twilio-paste/spinner';
export * from '@twilio-paste/absolute';
export * from '@twilio-paste/aspect-ratio';
export * from '@twilio-paste/box';
export * from '@twilio-paste/media-object';
export * from '@twilio-paste/screen-reader-only';
export * from '@twilio-paste/text';
export * from '@twilio-paste/truncate';
@@ -0,0 +1,62 @@
const {join} = require('path');
const {getRepoPackages} = require('../../../../tools/utils/getRepoPackages');
const {writeToFile} = require('../../../../tools/utils/writeToFile');

const BLACKLIST = ['@twilio-paste/core'];

const CORE_BUNDLE_PATH = join(__dirname, '../');
const CORE_BUNDLE_INDEX_PATH = join(CORE_BUNDLE_PATH, 'src/index.tsx');
const CORE_BUNDLE_PACKAGE_PATH = join(CORE_BUNDLE_PATH, 'package.json');

// Given a list of packages, output the index.tsx exports string
function generateIndexFromPackageList(packageList) {
let output = '';
packageList.forEach(package => {
output = `${output}export * from '${package.name}';\n`;
});
return output;
}

// Given a list of packages, output the package.json dependencies field
function generateDependenciesFromPackageList(packageList) {
const dependencies = {};
packageList.forEach(package => {
dependencies[package.name] = `^${package.version}`;
});
return dependencies;
}

// Given a list of packages, output only the packages that belong in 'core'
function getAllCorePackages(packageList) {
return packageList.filter(item => {
const isCorePackage = item.location.includes('/paste-core/');
const isReleased = !item.private && item.version !== '0.0.1' && item.version !== '0.0.0';
const isNotBlacklisted = !BLACKLIST.includes(item.name);

return isCorePackage && isReleased && isNotBlacklisted;
});
}

// Main
(async () => {
// Use lerna to get all packages and their version info
const packageList = await getRepoPackages();

// Filter to all production ready core packages
const filteredPackageList = getAllCorePackages(packageList);

// Write into core's index file
const indexOutput = generateIndexFromPackageList(filteredPackageList);
writeToFile(CORE_BUNDLE_INDEX_PATH, indexOutput, {
successMessage: `[@twilio-paste/core] Exports have been successfully updated within: ${CORE_BUNDLE_INDEX_PATH}`,
});

// Update package dependencies
// eslint-disable-next-line global-require, import/no-dynamic-require
const packageJson = require(CORE_BUNDLE_PACKAGE_PATH);
const newPackageJson = {...packageJson, dependencies: generateDependenciesFromPackageList(filteredPackageList)};
writeToFile(CORE_BUNDLE_PACKAGE_PATH, newPackageJson, {
formatJson: true,
successMessage: `[@twilio-paste/core] Successfully updated dependencies.`,
});
})();
@@ -0,0 +1,13 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"references": [
{
"path": "../../../paste-theme-tokens"
}
]
}
@@ -0,0 +1,4 @@
{
"extends": "../../../tsconfig.json",
"include": ["src/**/*"]
}
@@ -16,6 +16,7 @@ const {
} = require('./utils');
const {iconTemplate} = require('./iconTemplate');
const {listTemplate} = require('./listTemplate');
const {writeToFile} = require('../../../tools/utils/writeToFile');

const BLACKLIST_FILES = ['.DS_Store'];

@@ -39,8 +40,8 @@ function performFileConversion(fileName, outputPath, options) {
const cleanedFileName = getOutputComponentName(fileName);
// Convert the SVG into our ideal format
const generatedComponent = await convertSvgToReact(cleanedFileName, fileContents, options);
fs.writeFile(outputPath, generatedComponent, 'utf8', writeFileError => {
maybeHandleError(`Couldn't write formatted SVG to disk`, writeFileError);
writeToFile(outputPath, generatedComponent, {
errorMessage: `Couldn't write formatted SVG to disk`,
});
});
}
@@ -56,8 +57,8 @@ const Actions = {

const iconList = reactDestinationFiles.filter(name => name !== '.DS_Store').map(name => name.replace('.tsx', ''));

fs.writeFile(path.join(__dirname, './../__IconList.tsx'), listTemplate(iconList), 'utf8', error => {
maybeHandleError(`Couldn't write formatted SVG to disk`, error);
writeToFile(path.join(__dirname, './../__IconList.tsx'), listTemplate(iconList), 'utf8', {
errorMessage: `Couldn't write formatted SVG to disk`,
});
},
convertNew: async () => {
@@ -5,10 +5,10 @@
*
* Until this bites us, we should automate this because not bumping peers has bit us.
*/
const fs = require('fs');
const chalk = require('chalk');
const {resolve} = require('path');
const {getRepoPackages} = require('./getRepoPackages');
const {writeToFile} = require('./writeToFile');

const isPasteDependency = packageName => packageName.includes('@twilio-paste/');
const getPasteDependencyList = dependencyObject => Object.keys(dependencyObject).filter(isPasteDependency);
@@ -36,14 +36,8 @@ async function updatePackagePeerDependencies(packageJsonPath, peerDepsList = [],
const newPackageJsonString = `${JSON.stringify(newPackageJson, null, 2)}\n`;

// Write it to file
fs.writeFile(packageJsonPath, newPackageJsonString, error => {
if (error) {
// eslint-disable-next-line no-console
console.log(error);
return false;
}
// eslint-disable-next-line no-console
console.log(chalk.green(`[${packageJsonData.name}] Successfully updated ${JSON.stringify(calibratedPeerDeps)}`));
writeToFile(packageJsonPath, newPackageJsonString, {
successMessage: `[${packageJsonData.name}] Successfully updated ${JSON.stringify(calibratedPeerDeps)}`,
});
}

@@ -1,5 +1,8 @@
const {join} = require('path');
const {runCmdJson} = require('./runCmd');

const CLI_PATH = join(__dirname, '../../node_modules/lerna/cli.js');

let repoPackages = null;

/*
@@ -17,7 +20,7 @@ async function getRepoPackages() {
return repoPackages;
}

repoPackages = await runCmdJson('./node_modules/lerna/cli.js', ['la', '--json']);
repoPackages = await runCmdJson(CLI_PATH, ['la', '--json']);
return repoPackages;
}

@@ -1,7 +1,6 @@
const fs = require('fs');
const chalk = require('chalk');
const {resolve} = require('path');
const {getRepoPackages} = require('./getRepoPackages');
const {writeToFile} = require('./writeToFile');

const CACHE_FILE_PATH = resolve(__dirname, '../.cache/packages.json');

@@ -12,14 +11,9 @@ const CACHE_FILE_PATH = resolve(__dirname, '../.cache/packages.json');
async function updatePackageCache() {
const packagesList = await getRepoPackages();

fs.writeFile(CACHE_FILE_PATH, JSON.stringify(packagesList, null, 2), error => {
if (error) {
// eslint-disable-next-line no-console
console.log(error);
return false;
}
// eslint-disable-next-line no-console
console.log(chalk.green(`[Monorepo cache] Cache was successfully saved to: ${CACHE_FILE_PATH}`));
writeToFile(CACHE_FILE_PATH, packagesList, {
formatJson: true,
successMessage: `[Monorepo cache] Cache was successfully saved to: ${CACHE_FILE_PATH}`,
});

return packagesList;
@@ -2,12 +2,12 @@
* Updates tsconfig.build.json with paste peerDependencies
* Updates devDependencies with paste peerDependencies
*/
const fs = require('fs');
const chalk = require('chalk');
const lodash = require('lodash');
const {resolve, relative} = require('path');
const {getRepoPackages} = require('./getRepoPackages');
const {sortObjectByKey} = require('./sortObjectByKey');
const {writeToFile} = require('./writeToFile');

const isPasteDependency = packageName => packageName.includes('@twilio-paste/');
const getPasteDependencyList = dependencyObject => Object.keys(dependencyObject).filter(isPasteDependency);
@@ -27,16 +27,12 @@ async function updateTsconfigFile(path, referencesList = [], packagesList) {

// write it back to the file
tsconfigData.references = references;
fs.writeFile(TSCONFIG_FILE_PATH, JSON.stringify(tsconfigData, null, 2), error => {
if (error != null) {
// eslint-disable-next-line no-console
console.log(chalk.red('[TSConfig] Writing Tsconfig file failed'));
throw error;
}
writeToFile(TSCONFIG_FILE_PATH, tsconfigData, {
formatJson: true,
errorMessage: '[TSConfig] Writing Tsconfig file failed',
});
}

// TODO
async function updatePackageDevDependencies(packageJsonPath, pastePeerDeps = [], packageJson) {
// Let's start by assuming we need to put all pastePeerDeps into devDeps
let missingDevDeps = pastePeerDeps;
@@ -64,14 +60,9 @@ async function updatePackageDevDependencies(packageJsonPath, pastePeerDeps = [],
devDependencies: sortObjectByKey(newDevDeps),
};

fs.writeFile(packageJsonPath, JSON.stringify(newPackageJson, null, 2), error => {
if (error) {
// eslint-disable-next-line no-console
console.log(error);
return false;
}
// eslint-disable-next-line no-console
console.log(chalk.green(`[${packageJson.name}] Successfully added ${missingDevDeps}`));
writeToFile(packageJsonPath, newPackageJson, {
formatJson: true,
successMessage: `[${packageJson.name}] Successfully added ${missingDevDeps}`,
});
}

@@ -0,0 +1,24 @@
const chalk = require('chalk');
const {writeFile} = require('fs');

function writeToFile(filePath, content, {successMessage, errorMessage, formatJson = false}) {
const output = formatJson ? JSON.stringify(content, null, 2) : content;

writeFile(filePath, output, 'utf8', error => {
if (error) {
if (errorMessage != null) {
// eslint-disable-next-line no-console
console.log(chalk.red(errorMessage));
}
// eslint-disable-next-line no-console
console.log(error);
return false;
}
if (successMessage != null) {
// eslint-disable-next-line no-console
console.log(chalk.green(successMessage));
}
});
}

module.exports = {writeToFile};

1 comment on commit f6ab2eb

@now

This comment has been minimized.

Please sign in to comment.
You can’t perform that action at this time.