Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/typescript support #214

Merged
merged 3 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 7 additions & 21 deletions packages/react-scripts/config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,21 @@ module.exports = {
componentsBuild: resolveApp('build/components'),
patternsBuild: resolveApp('build/patterns'),
appPublic: resolveApp('public'),
appIndexJs: resolveApp('src/index.js'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
appJsConfig: resolveApp('jsconfig.json'),
componentsDir: resolveApp('src/components'),
componentsJs: resolveApp('src/components/index.js'),
componentsStaticJS: resolveApp('src/components/static.js'),
patternsDir: resolveApp('src/patterns'),
patternsJs: resolveApp('src/patterns/index.js'),
styleguideIndexJs: resolveApp('src/styleguide/index.js'),
styleguideHtml: resolveApp('src/styleguide/styleguide.html'),
scriptsDir: resolveApp('src/scripts'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
publicUrlOrPath,
libDir: resolveApp('src/lib'),
icons: resolveApp('src/assets/icons'),
tokens: resolveApp('src/lib/tokens.js'),
tokens: resolveModule(resolveApp, 'src/lib/tokens'),
staticJs: resolveModule(resolveApp, 'src/scripts/index'),
};

// @remove-on-eject-begin
Expand All @@ -98,27 +92,21 @@ module.exports = {
componentsBuild: resolveApp('build/components'),
patternsBuild: resolveApp('build/patterns'),
appPublic: resolveApp('public'),
appIndexJs: resolveApp('src/index.js'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
appJsConfig: resolveApp('jsconfig.json'),
componentsDir: resolveApp('src/components'),
componentsJs: resolveApp('src/components/index.js'),
componentsStaticJs: resolveApp('src/components/static.js'),
patternsDir: resolveApp('src/patterns'),
patternsJs: resolveApp('src/patterns/index.js'),
styleguideIndexJs: resolveApp('src/styleguide/index.js'),
styleguideHtml: resolveApp('src/styleguide/styleguide.html'),
scriptsDir: resolveApp('src/scripts'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
publicUrlOrPath,
libDir: resolveApp('src/lib'),
icons: resolveApp('src/assets/icons'),
tokens: resolveApp('src/lib/tokens.js'),
tokens: resolveModule(resolveApp, 'src/lib/tokens'),
staticJs: resolveModule(resolveApp, 'src/scripts/index'),
// These properties only exist before ejecting:
ownPath: resolveOwn('.'),
ownNodeModules: resolveOwn('node_modules'), // This is empty on npm 3
Expand Down Expand Up @@ -156,10 +144,8 @@ if (
publicUrlOrPath,
componentsDir: resolveApp('src/components'),
libDir: resolveApp('src/lib'),
patternsDir: resolveApp('src/patterns'),
styleguideIndexJs: resolveApp('src/styleguide/index.js'),
styleguideHtml: resolveApp('src/styleguide/styleguide.html'),
icons: resolveApp('src/assets/icons'),
staticJs: resolveModule(resolveApp, 'src/scripts/index'),
// These properties only exist before ejecting:
ownPath: resolveOwn('.'),
ownNodeModules: resolveOwn('node_modules'),
Expand Down
197 changes: 108 additions & 89 deletions packages/react-scripts/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,100 +77,119 @@ const spaHtmlPaths = Object.entries(spaPaths).reduce((acc, [key, value]) => {
return acc;
}, {});

const staticPath = path.join(paths.appSrc, 'scripts', 'index.js');

// Generate configuration
const config = [
configFactory('production', {
entries: {
app: path.join(paths.appSrc, 'index.js'),
...(fs.existsSync(staticPath) && { static: staticPath }),
...getEntries('lib', paths.libDir, '/*.{js,scss,css}'),
...spaEntries,
},
spaHtmlPaths,
}),
configFactory('lib', {
entries: {
...getEntries('components', paths.componentsDir, '/*.{js,scss,css}'),
...getEntries('components', paths.componentsDir, '/**/index.js'),
...getEntries('components', paths.componentsDir, '/**/*.static.js'),
},
}),
];

// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
return measureFileSizesBeforeBuild(paths.appBuild);
})
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
return build(previousFileSizes);
})
.then(
({ stats, previousFileSizes, warnings }) => {
if (warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green('Compiled successfully.\n'));
const appConfig = configFactory('production', {
entries: {
app: paths.appIndexJs,
...(fs.existsSync(paths.staticJs) && { static: paths.staticJs }),
...getEntries('lib', paths.libDir, '/*.{js,jsx,ts,tsx,scss,css}'),
...spaEntries,
},
spaHtmlPaths,
});

const componentsConfig = configFactory('lib', {
entries: {
...getEntries(
'components',
paths.componentsDir,
'/*.{js,jsx,ts,tsx,scss,css}'
),
...getEntries(
'components',
paths.componentsDir,
'/**/index.{js,jsx,ts,tsx}'
),
...getEntries(
'components',
paths.componentsDir,
'/**/*.static.{js,jsx,ts,tsx}'
),
},
});

const run = async () => {
await runBuild(appConfig, 'app');
await runBuild(componentsConfig, 'components');
};

run();

async function runBuild(config, buildType) {
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
return checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
return measureFileSizesBeforeBuild(paths.appBuild);
})
.then(previousFileSizes => {
if (buildType === 'app') {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Merge with the public folder
copyPublicFolder();
}
// Start the webpack build
return build(previousFileSizes, config, buildType);
})
.then(
({ stats, previousFileSizes, warnings }) => {
if (warnings.length) {
console.log(chalk.yellow(`Compiled ${buildType} with warnings.\n`));
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green(`Compiled ${buildType} successfully.\n`));
}

console.log('File sizes after gzip:\n');
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
console.log();
},
err => {
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
if (tscCompileOnError) {
console.log(
chalk.yellow(
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
)
console.log('File sizes after gzip:\n');
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
printBuildError(err);
} else {
console.log(chalk.red('Failed to compile.\n'));
printBuildError(err);
process.exit(1);
console.log();
},
err => {
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
if (tscCompileOnError) {
console.log(
chalk.yellow(
'Compiled with the following buildType errors (you may want to check these before deploying your app):\n'
)
);
printBuildError(err);
} else {
console.log(chalk.red('Failed to compile.\n'));
printBuildError(err);
process.exit(1);
}
}
}
)
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
)
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
}

// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
function build(previousFileSizes, config, buildType) {
// We used to support resolving modules according to `NODE_PATH`.
// This now has been deprecated in favor of jsconfig/tsconfig.json
// This lets you use absolute paths in imports inside large monorepos:
Expand All @@ -183,7 +202,7 @@ function build(previousFileSizes) {
console.log();
}

console.log('Creating an optimized production build...');
console.log(`Creating an optimized production build of ${buildType}...`);

const compiler = webpack(config);
return new Promise((resolve, reject) => {
Expand Down
22 changes: 9 additions & 13 deletions packages/react-scripts/scripts/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,15 @@ choosePort(HOST, DEFAULT_PORT)
{}
);

const staticPath = path.join(paths.appSrc, 'scripts', 'index.js');

const configs = [
configFactory('development', {
entries: {
app: path.join(paths.appSrc, 'index.js'),
...(fs.existsSync(staticPath) && { static: staticPath }),
...getEntries('lib', paths.libDir, '/*.{js,scss,css}'),
...spaEntries,
},
spaHtmlPaths,
}),
];
const configs = configFactory('development', {
entries: {
app: paths.appIndexJs,
...(fs.existsSync(paths.staticJs) && { static: paths.staticJs }),
...getEntries('lib', paths.libDir, '/*.{js,jsx,ts,tsx,scss,css}'),
...spaEntries,
},
spaHtmlPaths,
});

const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-scripts/scripts/utils/getEntries.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function getEntries(type, dirPath, globRegex) {

let entryName = path
// get rid of extension from entry name
.join(type, localPath.split(/(\.js|\.css|\.scss)$/)[0])
.join(type, localPath.split(/(\.js|\.jsx|\.ts|\.tsx|\.css|\.scss)$/)[0])
// remove leading slash
.replace(/^\/|\/$/g, '');

Expand Down
18 changes: 16 additions & 2 deletions packages/react-scripts/scripts/utils/getSpaPaths.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@

const glob = require('glob');
const path = require('path');
const fs = require('fs');

const paths = require('../../config/paths');

const resolveEntry = entryName => {
const entryPath = path.join(paths.appSrc, entryName);
const extension = paths.moduleFileExtensions.find(extension =>
fs.existsSync(`${entryPath}.${extension}`)
);

if (extension) {
return `${entryPath}.${extension}`;
}

return `${entryPath}.js`;
};

function getSpaEntries() {
const htmlTemplates = [
...glob.sync(path.join(paths.appSrc, '*.html')),
Expand All @@ -15,9 +29,9 @@ function getSpaEntries() {
return htmlTemplates.reduce((acc, templatePath) => {
const entryName = path.basename(templatePath, '.html');

acc[entryName] = {
acc[entryName] = {
htmlTemplatePath: templatePath,
entryPath: path.join(paths.appSrc, `${entryName}.js`)
entryPath: resolveEntry(entryName),
};

return acc;
Expand Down