Skip to content

Commit

Permalink
Merge branch 'master' into transpile-only
Browse files Browse the repository at this point in the history
* master: (26 commits)
  (deps/lint): upgrade @typescript-eslint to support ?. and ?? (jaredpalmer#377)
  (ci): add a lint job so PRs will require passing lint (jaredpalmer#378)
  (clean): remove .rts_cache_* from storybook gitignore (jaredpalmer#375)
  Add optional chaining and nullish coalescing operators support (jaredpalmer#370)
  Added Storybook template (jaredpalmer#318)
  (fix/ci): GitHub Actions should run on PRs as well
  (fix/format): formatting of jaredpalmer#366 didn't pass lint
  Add prepare script to generated project (jaredpalmer#334)
  default jest to watch mode when not in CI (jaredpalmer#366)
  (fix): respect tsconfig esModuleInterop flag (jaredpalmer#327)
  fix: minor typo
  update rollup deps and plugins
  update to ts 3.7
  Remove unnecessary yarn install command in GH action
  update README.md
  update README.md
  Use node_modules/.cache/... as cacheRoot (jaredpalmer#329)
  fix(lint): Only default to src test if they exist (jaredpalmer#344)
  Fix error when providing babel/preset-env without options (jaredpalmer#350)
  Replaced some sync methods for their async version
  ...
  • Loading branch information
sebald committed Dec 19, 2019
2 parents 97fa112 + 843c676 commit 118dcb4
Show file tree
Hide file tree
Showing 51 changed files with 1,952 additions and 1,090 deletions.
23 changes: 19 additions & 4 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
name: Node CI

on: [push]
on: [push, pull_request]

jobs:
lint:
runs-on: ubuntu-latest

name: Lint on node 10.x and ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Use Node.js 10.x
uses: actions/setup-node@v1
with:
node-version: 10.x

- name: Install deps and build
run: yarn install --frozen-lockfile

- name: Lint codebase
run: yarn lint

test:
runs-on: ${{ matrix.os }}

Expand All @@ -20,9 +38,6 @@ jobs:
with:
node-version: ${{ matrix.node }}

- name: Install yarn package manager
run: npm install -g yarn

- name: Install deps and build
run: yarn install --frozen-lockfile

Expand Down
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
*.log
.DS_Store
node_modules
.rts2_cache_cjs
.rts2_cache_esm
.rts2_cache_umd
.rts2_cache_system
dist
tester
tester-react
package-lock.json
# Local Netlify folder
.netlify
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Despite all the recent hype, setting up a new TypeScript (x React) library can b
- [`npm run build` or `yarn build`](#npm-run-build-or-yarn-build)
- [`npm test` or `yarn test`](#npm-test-or-yarn-test)
- [`npm run lint` or `yarn lint`](#npm-run-lint-or-yarn-lint)
- [`prepare` script](#prepare-script)
- [Optimizations](#optimizations)
- [Development-only Expressions + Treeshaking](#development-only-expressions--treeshaking)
- [Rollup Treeshaking](#rollup-treeshaking)
Expand Down Expand Up @@ -55,7 +56,7 @@ TSDX comes with the "battery-pack included" and is part of a complete TypeScript

## Quick Start

```
```bash
npx tsdx create mylib
cd mylib
yarn start
Expand Down Expand Up @@ -90,6 +91,11 @@ By default, runs tests related to files changed since the last commit.
Runs Eslint with Prettier on .ts and .tsx files.
If you want to customize eslint you can add an `eslint` block to your package.json, or you can run `yarn lint --write-file` and edit the generated `.eslintrc.js` file.

### `prepare` script

Bundles and packages to the `dist` folder.
Runs automatically when you run either `npm publish` or `yarn publish`. The `prepare` script will run the equivalent of `npm run build` or `yarn build`. It will also be run if your module is installed as a git dependency (ie: `"mymodule": "github:myuser/mymodule#some-branch"`) so it can be depended on without checking the transpiled code into git.

## Optimizations

Aside from just bundling your module into different formats, TSDX comes with some optimizations for your convenience. They yield objectively better code and smaller bundle sizes.
Expand Down
18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@
"@babel/core": "^7.4.4",
"@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4",
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-regenerator": "^7.4.5",
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@rollup/plugin-json": "^4.0.0",
"@rollup/plugin-replace": "^2.2.1",
"@types/rimraf": "^2.0.2",
"@types/shelljs": "^0.8.5",
"@typescript-eslint/eslint-plugin": "^2.3.1",
"@typescript-eslint/parser": "^2.3.1",
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"ansi-escapes": "^4.2.1",
"asyncro": "^3.0.0",
"babel-eslint": "^10.0.3",
Expand Down Expand Up @@ -76,24 +80,22 @@
"mkdirp": "^0.5.1",
"ora": "^3.4.0",
"pascal-case": "^2.0.1",
"prettier": "^1.18.2",
"prettier": "^1.19.1",
"progress-estimator": "^0.2.2",
"rimraf": "^3.0.0",
"rollup": "^1.12.0",
"rollup": "^1.27.8",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^10.0.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.0.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-sourcemaps": "^0.4.2",
"rollup-plugin-terser": "^5.1.2",
"rollup-plugin-typescript2": "^0.24.3",
"rollup-plugin-typescript2": "^0.25.3",
"sade": "^1.4.2",
"shelljs": "^0.8.3",
"tiny-glob": "^0.2.6",
"ts-jest": "^24.0.2",
"tslib": "^1.9.3",
"typescript": "^3.6.4"
"typescript": "^3.7.3"
},
"devDependencies": {
"@types/ansi-escapes": "^4.0.0",
Expand Down
6 changes: 5 additions & 1 deletion src/babelPluginTsdx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ export const babelPluginTsdx = babelPlugin.custom((babelCore: any) => ({
name: '@babel/plugin-proposal-class-properties',
loose: true,
},
// Adds syntax support for optional chaining (.?)
{ name: '@babel/plugin-proposal-optional-chaining' },
// Adds syntax support for default value using ?? operator
{ name: '@babel/plugin-proposal-nullish-coalescing-operator' },
{
name: '@babel/plugin-transform-regenerator',
async: false,
Expand Down Expand Up @@ -120,7 +124,7 @@ export const babelPluginTsdx = babelPlugin.custom((babelCore: any) => ({
modules: false,
exclude: merge(
['transform-async-to-generator', 'transform-regenerator'],
preset.options.exclude || []
(preset.options && preset.options.exclude) || []
),
}
),
Expand Down
46 changes: 31 additions & 15 deletions src/createEslintConfig.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,57 @@
import fs from 'fs';
import path from 'path';
import util from 'util';
import { CLIEngine } from 'eslint';
import { PackageJson } from './types';
import { getReactVersion } from './utils';

interface CreateEslintConfigArgs {
pkg: PackageJson;
rootDir: string;
writeFile: boolean;
}
export function createEslintConfig({
export async function createEslintConfig({
pkg,
rootDir,
writeFile,
}: CreateEslintConfigArgs): CLIEngine.Options['baseConfig'] {
}: CreateEslintConfigArgs): Promise<CLIEngine.Options['baseConfig']> {
const isReactLibrary = Boolean(getReactVersion(pkg));

const config = {
extends: [
'react-app',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
settings: {
react: {
// Fix for https://github.com/jaredpalmer/tsdx/issues/279
version: isReactLibrary ? 'detect' : '999.999.999',
},
},
};

if (writeFile) {
const file = path.join(rootDir, '.eslintrc.js');
if (fs.existsSync(file)) {
if (!writeFile) {
return config;
}

const file = path.join(rootDir, '.eslintrc.js');
try {
await util.promisify(fs.writeFile)(
file,
`module.exports = ${JSON.stringify(config, null, 2)}`,
{ flag: 'wx' }
);
} catch (e) {
if (e.code === 'EEXIST') {
console.error(
'Error trying to save the Eslint configuration file:',
`${file} already exists.`
);
} else {
try {
fs.writeFileSync(
file,
`module.exports = ${JSON.stringify(config, null, 2)}`
);
} catch (e) {
console.error(e);
}
console.error(e);
}
}

return config;
return config;
}
}
31 changes: 21 additions & 10 deletions src/createRollupConfig.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { safeVariableName, safePackageName, external } from './utils';
import {
safeVariableName,
safePackageName,
external,
resolveApp,
} from './utils';
import { paths } from './constants';
import { terser } from 'rollup-plugin-terser';
import { DEFAULT_EXTENSIONS } from '@babel/core';
// import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import json from '@rollup/plugin-json';
import replace from '@rollup/plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import sourceMaps from 'rollup-plugin-sourcemaps';
import typescript from 'rollup-plugin-typescript2';
import { extractErrors } from './errors/extractErrors';
import { babelPluginTsdx } from './babelPluginTsdx';
import { TsdxOptions } from './types';
import * as fs from 'fs-extra';

const errorCodeOpts = {
errorMapFilePath: paths.appErrorsJson,
Expand All @@ -20,8 +26,8 @@ const errorCodeOpts = {
// shebang cache map thing because the transform only gets run once
let shebang: any = {};

export function createRollupConfig(opts: TsdxOptions) {
const findAndRecordErrorCodes = extractErrors({
export async function createRollupConfig(opts: TsdxOptions) {
const findAndRecordErrorCodes = await extractErrors({
...errorCodeOpts,
...opts,
});
Expand All @@ -39,6 +45,11 @@ export function createRollupConfig(opts: TsdxOptions) {
.filter(Boolean)
.join('.');

let tsconfigJSON;
try {
tsconfigJSON = fs.readJSONSync(resolveApp('tsconfig.json'));
} catch (e) {}

return {
// Tell Rollup the entry point to the package
input: opts.input,
Expand All @@ -58,8 +69,8 @@ export function createRollupConfig(opts: TsdxOptions) {
// Do not let Rollup call Object.freeze() on namespace import objects
// (i.e. import * as namespaceImportObject from...) that are accessed dynamically.
freeze: false,
// Do not let Rollup add a `__esModule: true` property when generating exports for non-ESM formats.
esModule: false,
// Respect tsconfig esModuleInterop when setting __esModule.
esModule: tsconfigJSON ? tsconfigJSON.esModuleInterop : false,
// Rollup has treeshaking by default, but we can optimize it further...
treeshake: {
// We assume reading a property of an object never has side-effects.
Expand Down Expand Up @@ -88,8 +99,8 @@ export function createRollupConfig(opts: TsdxOptions) {
},
plugins: [
!!opts.extractErrors && {
transform(source: any) {
findAndRecordErrorCodes(source);
async transform(source: any) {
await findAndRecordErrorCodes(source);
return source;
},
},
Expand Down Expand Up @@ -128,7 +139,7 @@ export function createRollupConfig(opts: TsdxOptions) {
},
typescript({
typescript: require('typescript'),
cacheRoot: `./.rts2_cache_${opts.format}`,
cacheRoot: `./node_modules/.cache/tsdx/${opts.format}/`,
tsconfig: opts.tsconfig,
tsconfigDefaults: {
compilerOptions: {
Expand Down
20 changes: 10 additions & 10 deletions src/errors/extractErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const babylonOptions = {
],
};

export function extractErrors(opts: any) {
export async function extractErrors(opts: any) {
if (!opts || !('errorMapFilePath' in opts)) {
throw new Error(
'Missing options. Ensure you pass an object with `errorMapFilePath`.'
Expand All @@ -42,10 +42,10 @@ export function extractErrors(opts: any) {
const errorMapFilePath = opts.errorMapFilePath;
let existingErrorMap: any;
try {
// Using `fs.readFileSync` instead of `require` here, because `require()`
// Using `fs.readFile` instead of `require` here, because `require()`
// calls are cached, and the cache map is not properly invalidated after
// file changes.
existingErrorMap = JSON.parse(fs.readFileSync(errorMapFilePath, 'utf8'));
existingErrorMap = JSON.parse(await fs.readFile(errorMapFilePath, 'utf8'));
} catch (e) {
existingErrorMap = {};
}
Expand Down Expand Up @@ -89,20 +89,20 @@ export function extractErrors(opts: any) {
existingErrorMap[errorMsgLiteral] = '' + currentID++;
}

function flush(cb?: any) {
async function flush() {
const prettyName = pascalCase(safeVariableName(opts.name));
// Ensure that the ./src/errors directory exists or create it
fs.ensureDirSync(paths.appErrors);
await fs.ensureDir(paths.appErrors);

// Output messages to ./errors/codes.json
fs.writeFileSync(
await fs.writeFile(
errorMapFilePath,
JSON.stringify(invertObject(existingErrorMap), null, 2) + '\n',
'utf-8'
);

// Write the error files, unless they already exist
fs.writeFileSync(
await fs.writeFile(
paths.appErrors + '/ErrorDev.js',
`
function ErrorDev(message) {
Expand All @@ -116,7 +116,7 @@ export default ErrorDev;
'utf-8'
);

fs.writeFileSync(
await fs.writeFile(
paths.appErrors + '/ErrorProd.js',
`
function ErrorProd(code) {
Expand All @@ -138,8 +138,8 @@ export default ErrorProd;
);
}

return function extractErrors(source: any) {
return async function extractErrors(source: any) {
transform(source);
flush();
await flush();
};
}
4 changes: 2 additions & 2 deletions src/getInstallCmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ let cmd: InstallCommand;

export type InstallCommand = 'yarn' | 'npm';

export default function getInstallCmd(): InstallCommand {
export default async function getInstallCmd(): Promise<InstallCommand> {
if (cmd) {
return cmd;
}

try {
execa.sync('yarnpkg', ['--version']);
await execa('yarnpkg', ['--version']);
cmd = 'yarn';
} catch (e) {
cmd = 'npm';
Expand Down
Loading

0 comments on commit 118dcb4

Please sign in to comment.