From 4faf10edbc144108906f7c9f2d3a45c9d249caf8 Mon Sep 17 00:00:00 2001
From: Swashata Ghosh
Date: Mon, 22 Oct 2018 15:10:03 +0530
Subject: [PATCH] feat: add ts checker webpack plugin
Only when tsconfig.json is found in the project.
See #15
---
.../plugin/inc/class-wpackio-plugin-init.php | 1 +
examples/plugin/package.json | 4 +-
examples/plugin/src/ts/main.ts | 14 +++++++
examples/plugin/src/ts/module.ts | 3 ++
examples/plugin/tsconfig.json | 17 ++++++++
examples/plugin/wpackio.project.js | 6 +++
.../config/WebpackConfigHelper.spec.ts | 18 ++++++++
packages/scripts/package.json | 1 +
.../scripts/src/config/WebpackConfigHelper.ts | 28 +++++++++++++
site/src/pages/index.js | 6 ++-
yarn.lock | 41 ++++++++++++++++++-
11 files changed, 136 insertions(+), 3 deletions(-)
create mode 100644 examples/plugin/src/ts/main.ts
create mode 100644 examples/plugin/src/ts/module.ts
create mode 100644 examples/plugin/tsconfig.json
diff --git a/examples/plugin/inc/class-wpackio-plugin-init.php b/examples/plugin/inc/class-wpackio-plugin-init.php
index 63d88b38e..1ad72bd12 100644
--- a/examples/plugin/inc/class-wpackio-plugin-init.php
+++ b/examples/plugin/inc/class-wpackio-plugin-init.php
@@ -20,6 +20,7 @@ function plugin_enqueue() {
$this->enqueue->enqueue( 'app', 'main', [] );
$this->enqueue->enqueue( 'app', 'mobile', [] );
$this->enqueue->enqueue( 'foo', 'main', [] );
+ $this->enqueue->enqueue( 'tsapp', 'main', [] );
}
function reactapp( $atts, $content = null ) {
diff --git a/examples/plugin/package.json b/examples/plugin/package.json
index 356621296..e76f6ba89 100644
--- a/examples/plugin/package.json
+++ b/examples/plugin/package.json
@@ -8,7 +8,8 @@
"private": true,
"devDependencies": {
"autoprefixer": "^9.1.5",
- "node-sass": "^4.9.3"
+ "node-sass": "^4.9.3",
+ "typescript": "^3.1.3"
},
"scripts": {
"bootstrap": "wpackio-scripts bootstrap",
@@ -16,6 +17,7 @@
"exbuild": "wpackio-scripts build"
},
"dependencies": {
+ "@types/webpack-env": "^1.13.6",
"@wpackio/scripts": "^1.2.1",
"react": "^16.5.2",
"react-bootstrap": "^1.0.0-beta.1",
diff --git a/examples/plugin/src/ts/main.ts b/examples/plugin/src/ts/main.ts
new file mode 100644
index 000000000..60dbda46c
--- /dev/null
+++ b/examples/plugin/src/ts/main.ts
@@ -0,0 +1,14 @@
+///
+
+import { strRepeat } from './module';
+
+console.log(strRepeat('foo', 10));
+console.log(strRepeat('foo', 10));
+console.log(strRepeat('foo', 10));
+
+if (module.hot) {
+ module.hot.accept('./module.ts', () => {
+ const rp = require('./module').strRepeat;
+ console.log(rp('foo', 10));
+ });
+}
diff --git a/examples/plugin/src/ts/module.ts b/examples/plugin/src/ts/module.ts
new file mode 100644
index 000000000..772338786
--- /dev/null
+++ b/examples/plugin/src/ts/module.ts
@@ -0,0 +1,3 @@
+export function strRepeat(item: string, times: number): string {
+ return item.repeat(times);
+}
diff --git a/examples/plugin/tsconfig.json b/examples/plugin/tsconfig.json
new file mode 100644
index 000000000..83581c242
--- /dev/null
+++ b/examples/plugin/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "esnext",
+ "moduleResolution": "node",
+ "lib": ["esnext", "dom", "dom.iterable"],
+ "allowJs": true,
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "noEmit": true,
+ "skipLibCheck": true,
+ "strict": true
+ },
+ "include": ["src/ts"]
+}
diff --git a/examples/plugin/wpackio.project.js b/examples/plugin/wpackio.project.js
index 43f897e61..733aacf73 100644
--- a/examples/plugin/wpackio.project.js
+++ b/examples/plugin/wpackio.project.js
@@ -42,6 +42,12 @@ module.exports = {
main: ['./src/reactapp/index.jsx'],
},
},
+ {
+ name: 'tsapp',
+ entry: {
+ main: ['./src/ts/main.ts'],
+ },
+ },
],
// Output path relative to the context directory
// We need relative path here, else, we can not map to publicPath
diff --git a/packages/scripts/__tests__/config/WebpackConfigHelper.spec.ts b/packages/scripts/__tests__/config/WebpackConfigHelper.spec.ts
index b0b963a49..8fc56014a 100644
--- a/packages/scripts/__tests__/config/WebpackConfigHelper.spec.ts
+++ b/packages/scripts/__tests__/config/WebpackConfigHelper.spec.ts
@@ -1,5 +1,7 @@
import { PresetOptions } from '@wpackio/babel-preset-base/lib/preset';
+import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import miniCssExtractPlugin from 'mini-css-extract-plugin';
+import path from 'path';
import webpack from 'webpack';
import { webpackOptionsOverrideFunction } from '../../src/config/project.config.default';
import { WebpackConfigHelper } from '../../src/config/WebpackConfigHelper';
@@ -130,6 +132,22 @@ describe('CreateWebPackConfig', () => {
const plugins = cwc.getPlugins();
expect(plugins).toMatchSnapshot();
});
+ test('has fork ts checker when tsconfig.json is present', () => {
+ const cwc = new WebpackConfigHelper(
+ projectConfig.files[0],
+ getConfigFromProjectAndServer(projectConfig, serverConfig),
+ path.resolve(__dirname, '../../'), // it's a hack cause the project has tsconfig.json
+ true
+ );
+ const plugins = cwc.getPlugins();
+ let hasTsChecker = false;
+ plugins.forEach(plug => {
+ if (plug instanceof ForkTsCheckerWebpackPlugin) {
+ hasTsChecker = true;
+ }
+ });
+ expect(hasTsChecker).toBeTruthy();
+ });
});
// getModule()
diff --git a/packages/scripts/package.json b/packages/scripts/package.json
index ed8cab131..582a10438 100644
--- a/packages/scripts/package.json
+++ b/packages/scripts/package.json
@@ -53,6 +53,7 @@
"figures": "^2.0.0",
"file-loader": "^2.0.0",
"find-up": "^3.0.0",
+ "fork-ts-checker-webpack-plugin": "^0.4.10",
"gradient-string": "^1.2.0",
"handlebars": "^4.0.12",
"inquirer": "^6.2.0",
diff --git a/packages/scripts/src/config/WebpackConfigHelper.ts b/packages/scripts/src/config/WebpackConfigHelper.ts
index cc5d1fb31..413dac419 100644
--- a/packages/scripts/src/config/WebpackConfigHelper.ts
+++ b/packages/scripts/src/config/WebpackConfigHelper.ts
@@ -3,6 +3,8 @@ import {
PresetOptions,
} from '@wpackio/babel-preset-base/lib/preset';
import cleanWebpackPlugin from 'clean-webpack-plugin';
+import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
+import fs from 'fs';
import miniCssExtractPlugin from 'mini-css-extract-plugin';
import path from 'path';
import WatchMissingNodeModulesPlugin from 'react-dev-utils/WatchMissingNodeModulesPlugin';
@@ -260,6 +262,21 @@ export class WebpackConfigHelper {
entrypointsKey: 'wpackioEp',
}),
];
+ // Add ts checker plugin if project has tsconfig.json
+ const tsconfigPath = path.resolve(this.cwd, './tsconfig.json');
+ if (this.fileExists(tsconfigPath)) {
+ const tsConfig: { tsconfig: string; tslint?: string | boolean } = {
+ tsconfig: tsconfigPath,
+ };
+ plugins.push(
+ new ForkTsCheckerWebpackPlugin({
+ tsconfig: tsconfigPath,
+ tslint: undefined,
+ async: false,
+ silent: true,
+ })
+ );
+ }
// Add development specific plugins
if (this.isDev) {
// Hot Module Replacement
@@ -558,4 +575,15 @@ ${bannerConfig.copyrightText}${bannerConfig.credit ? creditNote : ''}`,
// Otherwise just return default
return defaults;
}
+
+ /**
+ * Check if file exists or not using fs API.
+ */
+ private fileExists(filepath: string): boolean {
+ try {
+ return fs.statSync(filepath).isFile();
+ } catch (_) {
+ return false;
+ }
+ }
}
diff --git a/site/src/pages/index.js b/site/src/pages/index.js
index 0a95d7947..37b8e0566 100644
--- a/site/src/pages/index.js
+++ b/site/src/pages/index.js
@@ -39,7 +39,11 @@ const IndexPage = ({ data: { mission } }) => (
# initiate the tooling to your existing project
- npx @wpackio/scripts bootstrap
+ npx @wpackio/cli
+
+ # bootstrap project
+
+ npm run bootstrap
# start development server
diff --git a/yarn.lock b/yarn.lock
index ceaee1f7f..46b627f64 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1473,6 +1473,10 @@
"@types/memory-fs" "*"
"@types/webpack" "*"
+"@types/webpack-env@^1.13.6":
+ version "1.13.6"
+ resolved "http://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.6.tgz#128d1685a7c34d31ed17010fc87d6a12c1de6976"
+
"@types/webpack-hot-middleware@^2.16.4":
version "2.16.4"
resolved "https://registry.yarnpkg.com/@types/webpack-hot-middleware/-/webpack-hot-middleware-2.16.4.tgz#258ecf2ae0ee80a988cc65547b24608fe10be440"
@@ -2720,7 +2724,7 @@ chokidar@1.7.0:
optionalDependencies:
fsevents "^1.0.0"
-chokidar@^2.0.2, chokidar@^2.0.3:
+chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26"
dependencies:
@@ -4573,6 +4577,21 @@ forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+fork-ts-checker-webpack-plugin@^0.4.10:
+ version "0.4.10"
+ resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-0.4.10.tgz#e96f87ea599af4501c1a69f44ecfb3163bbf30b9"
+ dependencies:
+ babel-code-frame "^6.22.0"
+ chalk "^2.4.1"
+ chokidar "^2.0.4"
+ lodash.endswith "^4.2.1"
+ lodash.isfunction "^3.0.8"
+ lodash.isstring "^4.0.1"
+ lodash.startswith "^4.2.1"
+ minimatch "^3.0.4"
+ resolve "^1.5.0"
+ tapable "^1.0.0"
+
form-data@~2.3.1, form-data@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
@@ -6405,6 +6424,10 @@ lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
+lodash.endswith@^4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09"
+
lodash.get@^4.0, lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
@@ -6417,6 +6440,14 @@ lodash.isfinite@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
+lodash.isfunction@^3.0.8:
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051"
+
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -6429,6 +6460,10 @@ lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+lodash.startswith@^4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/lodash.startswith/-/lodash.startswith-4.2.1.tgz#c598c4adce188a27e53145731cdc6c0e7177600c"
+
lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
@@ -9939,6 +9974,10 @@ typescript@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.1.tgz#3362ba9dd1e482ebb2355b02dfe8bcd19a2c7c96"
+typescript@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
+
ua-parser-js@0.7.17:
version "0.7.17"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"