Skip to content

Commit

Permalink
feat(infrastructure): build JS from TS (#547)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Goo authored Dec 20, 2018
1 parent 226ce29 commit 740c467
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 42 deletions.
2 changes: 1 addition & 1 deletion packages/floating-label/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import * as React from 'react';
import * as classnames from 'classnames';
// no mdc .d.ts
// @ts-ignore
import {MDCFloatingLabelFoundation} from '@material/floating-label';
import {MDCFloatingLabelFoundation} from '@material/floating-label/dist/mdc.floatingLabel';

export interface FloatingLabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
className?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/line-ripple/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import * as React from 'react';
import * as classnames from 'classnames';
// no mdc .d.ts
// @ts-ignore
import {MDCLineRippleFoundation} from '@material/line-ripple';
import {MDCLineRippleFoundation} from '@material/line-ripple/dist/mdc.lineRipple';

export interface LineRippleProps extends React.HTMLProps<HTMLDivElement> {
className?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/text-field/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import * as React from 'react';
import * as classnames from 'classnames';
// @ts-ignore
import {MDCTextFieldFoundation} from '@material/textfield';
import {MDCTextFieldFoundation} from '@material/textfield/dist/mdc.textfield';
// @ts-ignore
import {VALIDATION_ATTR_WHITELIST} from '@material/textfield/constants';

Expand Down
2 changes: 1 addition & 1 deletion packages/text-field/helper-text/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import * as React from 'react';
import * as classnames from 'classnames';
// no mdc .d.ts
// @ts-ignore
import {MDCTextFieldHelperTextFoundation} from '@material/textfield';
import {MDCTextFieldHelperTextFoundation} from '@material/textfield/dist/mdc.textfield';

export interface HelperTextProps {
'aria-hidden': boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/text-field/icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import * as React from 'react';
import * as classnames from 'classnames';
// @ts-ignore
import {MDCTextFieldIconFoundation} from '@material/textfield';
import {MDCTextFieldIconFoundation} from '@material/textfield/dist/mdc.textfield';

export interface IconProps extends React.HTMLProps<HTMLOrSVGElement> {
disabled: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/text-field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import * as React from 'react';
import * as classnames from 'classnames';
// no mdc .d.ts
// @ts-ignore
import {MDCTextFieldFoundation, MDCTextFieldAdapter} from '@material/textfield';
import {MDCTextFieldFoundation, MDCTextFieldAdapter} from '@material/textfield/dist/mdc.textfield';
import Input, {InputProps} from './Input';
import Icon, {IconProps} from './icon/index';
import HelperText, {HelperTextProps} from './helper-text/index';
Expand Down
47 changes: 26 additions & 21 deletions packages/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@ const {readdirSync, lstatSync} = require('fs');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const {readMaterialPackages} = require('../scripts/package-json-reader');
const {convertToImportPaths} = require('../scripts/package-name-converter');
const {convertToImportMDCWebPaths} = require('../scripts/package-name-converter');
const {getDirectories} = require('../scripts/directory-reader');
const {importer} = require('./webpack.util');

const isDirectory = (source) => lstatSync(source).isDirectory();
const containsJsFile = (source) => readdirSync(source).some((file) => path.extname(file) === '.js');
const containsTsxFile = (source) => readdirSync(source).some((file) => path.extname(file) === '.tsx');

const getChunks = (source) =>
readdirSync(source)
.map((filename) => path.join(source, filename))
.filter((source) => isDirectory(source) && containsJsFile(source))
.filter((source) => isDirectory(source) && containsTsxFile(source))
.map((directoryPath) => directoryPath.replace('packages\/', ''));

const chunks = getChunks('./packages');
Expand All @@ -46,13 +47,12 @@ function getWebpackConfigs() {
const webpackConfigs = [];

chunks.forEach((chunk) => {
const jsPath = getAbsolutePath(`${chunk}/index.js`);
const tsxPath = getAbsolutePath(`${chunk}/index.tsx`);
const cssPath = getAbsolutePath(`${chunk}/index.scss`);

webpackConfigs.push(getJavaScriptWebpackConfig(jsPath, chunk, 'commonjs'));
webpackConfigs.push(getJavaScriptWebpackConfig(jsPath, chunk, false));
webpackConfigs.push(getJavaScriptWebpackConfig(jsPath, `${chunk}.min`, 'commonjs'));

webpackConfigs.push(getJavaScriptWebpackConfig(tsxPath, chunk, 'commonjs'));
webpackConfigs.push(getJavaScriptWebpackConfig(tsxPath, chunk, false));
webpackConfigs.push(getJavaScriptWebpackConfig(tsxPath, `${chunk}.min`, 'commonjs'));

webpackConfigs.push(getCssWebpackConfig(cssPath, chunk));
webpackConfigs.push(getCssWebpackConfig(cssPath, `${chunk}.min`));
Expand All @@ -70,16 +70,30 @@ function getCommonWebpackParams(entryPath, chunk, {isCss, modules}) {
filename: `${filename}${isCss ? '.css' : ''}${modules === false ? '.es' : ''}.js`,
libraryTarget: 'umd',
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
},
devtool: 'source-map',
};
}

function getReactMaterialExternals() {
return getDirectories('./packages').map((directory) => (
`react-${path.parse(directory).name}`
));
}

function getMaterialExternals() {
const externals = {};
const importPaths = convertToImportPaths(readMaterialPackages());
const importPaths = convertToImportMDCWebPaths(readMaterialPackages());
importPaths.forEach((importPath) => {
externals[importPath] = importPath;
externals[importPath] = `${importPath}.js`;
});

getReactMaterialExternals().forEach((path) => {
externals[`@material/${path}`] = `@material/${path}/dist/index.js`;
});

return externals;
}

Expand All @@ -96,17 +110,8 @@ function getJavaScriptWebpackConfig(entryPath, chunk, modules) {
),
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
options: {
babelrc: false,
compact: true,
presets: [['es2015', {modules}], 'react'],
plugins: [
'transform-class-properties',
'transform-object-rest-spread',
],
},
test: /\.ts(x)?$/,
loader: 'ts-loader',
}],
},
plugins: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const isDirectory = source => lstatSync(source).isDirectory();
const getDirectories = source =>
readdirSync(source).map(name => join(source, name)).filter(isDirectory);

function read(
function readScreenshotDirectory(
components = [],
path = resolve(__dirname, '../test/screenshot'),
parentDirectory = ''
Expand All @@ -20,12 +20,12 @@ function read(
// recursively get sub directories
const subDirectories = getDirectories(resolve(path, packageName));
if (subDirectories.length > 0) {
read(components, resolve(path, packageName), packageName);
readScreenshotDirectory(components, resolve(path, packageName), packageName);
}
components.push(`${parentDirectory ? parentDirectory + '/' : ''}${packageName}`);
});

return components;
}

module.exports = {read};
module.exports = {read: readScreenshotDirectory, getDirectories};
5 changes: 2 additions & 3 deletions scripts/package-name-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ const {basename} = require('path');

const dashedToCamel = (name) => name.replace(/-(\w)/g, (_, v) => v.toUpperCase());

const convertToImportPaths = (packageNames) => {
const importPaths = [];
convertToImportMDCWebPaths = (packageNames) => {
return packageNames.map((packageName) => {
const name = basename(packageName);
// this can be reverted when we change back to @material/foo-package-filename
Expand All @@ -12,4 +11,4 @@ const convertToImportPaths = (packageNames) => {
});
}

module.exports = {convertToImportPaths};
module.exports = {convertToImportMDCWebPaths};
30 changes: 24 additions & 6 deletions scripts/release/cp-pkgs.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,29 @@ function cpAsset(asset) {
.then(() => console.log(`cp ${asset} -> ${destDir}`));
}

Promise.all(globSync('build/*.{css,js,map}').map(cpAsset))
.then(() => {
console.log('done!');
})
.catch((err) => {
// takes assetPath, computes the destination file directory path
// and copies file into destination directory
function cpTypes(typeAsset) {
const {dir, base} = path.parse(typeAsset);
let destDir = dir.split('build/types/')[1];
destDir = destDir.split('/');
destDir.splice(2, 0, 'dist');
destDir = `${destDir.join('/')}/${base}`;
return cpFile(typeAsset, destDir)
.then(() => console.log(`cp ${typeAsset} -> ${destDir}`));
}

async function copyPackages() {
try {
await Promise.all(globSync('build/*.{css,js,map}').map(cpAsset));
console.log('-- Copied CSS, JS, and Map Files to Destination Directory');
await Promise.all(globSync('build/types/packages/**/*.d.ts').map(cpTypes));
console.log('-- Copied Typescript Type Files to Destination Directory');
} catch (err) {
console.error(`Error encountered copying assets: ${err}`);
process.exit(1);
});
}
}

copyPackages();

2 changes: 1 addition & 1 deletion test/screenshot/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const {read: readComponents} = require('../../scripts/screenshot-directory-reader');
const {read: readComponents} = require('../../scripts/directory-reader');
const {importer} = require('../../packages/webpack.util');

module.exports = {
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "gts/tsconfig-google.json",
"compilerOptions": {
"outDir": "./build/",
"outDir": "./types/",
"declaration": true,
"sourceMap": true,
"strictNullChecks": true,
Expand All @@ -16,6 +16,6 @@
"compileOnSave": true,
"exclude": [
"node_modules",
"build",
"build"
]
}

0 comments on commit 740c467

Please sign in to comment.