diff --git a/.gitignore b/.gitignore index e1ab197..acb0d6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /node_modules /.eslintcache -/samples/dist +/samples/*/dist diff --git a/lib/bundle/config.js b/lib/bundle/config.js index c8d564b..b1f510e 100644 --- a/lib/bundle/config.js +++ b/lib/bundle/config.js @@ -24,22 +24,32 @@ module.exports = generateConfig; // * `moduleName` determines the global variable to hold the entry point's // exports (if any) // * `transpiler.features` determines the language features to be supported -// within source code (e.g. `["es2015", "jsx"]`) +// within source code (e.g. `["es2015", "typescript", "jsx"]`) +// * `transpiler.typescript` are TypeScript-specific options // * `transpiler.jsx` are JSX-specific options (e.g. `{ pragma: "createElement" }`) // * `transpiler.exclude` is a list of modules for which to skip transpilation // (e.g. `["jquery"]`, perhaps due to an already optimized ES5 distribution) function generateConfig({ extensions = [], // eslint-disable-next-line indent externals, format, compact, moduleName, transpiler }) { + let plugins = []; if(transpiler) { - let { features } = transpiler; - if(features && features.includes("jsx")) { - extensions = [".jsx"].concat(extensions); - } + let { features = [] } = transpiler; + if(features.includes("typescript")) { // XXX: special-casing + let ts = requireOptional("rollup-plugin-typescript2", + "failed to activate TypeScript", "faucet-pipeline-typescript"); + // TODO: provide defaults and abstractions for low-level options + let { typescript } = transpiler; + plugins.push(typescript ? ts(typescript) : ts()); + } else { + if(features.includes("jsx")) { + extensions = [".jsx"].concat(extensions); + } - let babel = requireOptional("rollup-plugin-babel", - "failed to activate transpiler", "faucet-pipeline-esnext"); - let settings = generateTranspilerConfig(transpiler); - transpiler = babel(settings); + let babel = requireOptional("rollup-plugin-babel", + "failed to activate transpiler", "faucet-pipeline-esnext"); + let settings = generateTranspilerConfig(transpiler); + plugins.push(babel(settings)); + } } let resolve = { jsnext: true }; @@ -47,7 +57,7 @@ function generateConfig({ extensions = [], // eslint-disable-next-line indent resolve.extensions = [".js"].concat(extensions); } - let plugins = (transpiler ? [transpiler] : []).concat([ + plugins = plugins.concat([ nodeResolve(resolve), commonjs({ include: "node_modules/**" }) ]); @@ -81,7 +91,7 @@ function generateConfig({ extensions = [], // eslint-disable-next-line indent }); } -function generateTranspilerConfig({ features, jsx = {}, exclude }) { +function generateTranspilerConfig({ features, jsx, exclude }) { let settings = {}; let plugins = []; @@ -102,7 +112,7 @@ function generateTranspilerConfig({ features, jsx = {}, exclude }) { } if(features.includes("jsx")) { - plugins.push(["transform-react-jsx", jsx]); + plugins.push(["transform-react-jsx", jsx || {}]); } if(plugins.length) { diff --git a/samples/faucet.config.js b/samples/esnext/faucet.config.js similarity index 92% rename from samples/faucet.config.js rename to samples/esnext/faucet.config.js index 3289fe5..da35e18 100644 --- a/samples/faucet.config.js +++ b/samples/esnext/faucet.config.js @@ -1,3 +1,5 @@ +"use strict"; + module.exports = { manifest: { file: "./dist/manifest.json" diff --git a/samples/index.js b/samples/esnext/index.js similarity index 100% rename from samples/index.js rename to samples/esnext/index.js diff --git a/samples/util.js b/samples/esnext/util.js similarity index 100% rename from samples/util.js rename to samples/esnext/util.js diff --git a/samples/typescript/faucet.config.js b/samples/typescript/faucet.config.js new file mode 100644 index 0000000..eb8454b --- /dev/null +++ b/samples/typescript/faucet.config.js @@ -0,0 +1,11 @@ +"use strict"; + +module.exports = { + js: [{ + source: "./index.ts", + target: "./dist/bundle.js", + transpiler: { + features: ["typescript"] + } + }] +}; diff --git a/samples/typescript/index.ts b/samples/typescript/index.ts new file mode 100644 index 0000000..112128f --- /dev/null +++ b/samples/typescript/index.ts @@ -0,0 +1,28 @@ +import { log, LogLevel } from "./util"; + +interface ComplexTitle { + main: string; + sub: string; +} + +interface ArticleInterface { + title: string | ComplexTitle; + authors: string[]; +} + +let generateArticle = (params: ArticleInterface) => { + let { title, authors } = params; + if(typeof title !== "string") { + log(LogLevel.Debug, "auto-generating title"); + title = `${title.main}: ${title.sub}`; + } + return title + "\n" + authors.join(", "); +}; + +generateArticle({ + title: { + main: "Hello World", + sub: "sup" + }, + authors: ["foo", "bar"] +}); diff --git a/samples/typescript/util.ts b/samples/typescript/util.ts new file mode 100644 index 0000000..8987d96 --- /dev/null +++ b/samples/typescript/util.ts @@ -0,0 +1,9 @@ +export enum LogLevel { Debug, Info, Critical } + +export function log(level: LogLevel, msg: string) { + if(level === LogLevel.Critical) { + console.error(msg); + } else { + console.log(msg); + } +}