Reputation: 5133
I'm using TS 1.7 and I'm trying to compile my project to one big file that I will be able to include in my html file.
My project structure looks like this:
-build // Build directory
-src // source root
--main.ts // my "Main" file that uses the imports my outer files
--subDirectories with more ts files.
-package.json
-tsconfig.json
my tsconfig file is:
{
"compilerOptions": {
"module":"amd",
"target": "ES5",
"removeComments": true,
"preserveConstEnums": true,
"outDir": "./build",
"outFile":"./build/build.js",
"sourceRoot": "./src/",
"rootDir": "./src/",
"sourceMap": true
}
}
When I build my project I expect the build.js file to be one big file compiled from my source. But ths build.js file is empty and I get all of my files compiled o js files.
Each of my TS files look a bit like this
import {blabla} from "../../bla/blas";
export default class bar implements someThing {
private variable : string;
}
What am I doing wrong ?
Upvotes: 126
Views: 173360
Reputation: 21
I similarly needed to compile multiple typescript files with import and exports to a single JS file, and found a solution.
tsc
to generate the single js file{
"compilerOptions" : {
"module" : "System",
"declaration" : false,
"baseUrl" : "./",
"outFile" : "../libs/bundle.js",
"alwaysStrict" : true,
"removeComments" : true,
},
"include": [
"./**/*.ts"
],
"exclude": [
"./out.d.ts"
]
}
In your index.html you will need to include the system.js bundle JS file (found at https://github.com/systemjs/systemjs/blob/main/dist/system.js). Additionally, you will need to append the systemjs extra naming support found at https://github.com/systemjs/systemjs/blob/main/dist/extras/named-register.js to system.js
Include your compile bundle.js file in your index.html
Include a script that imports all the named imports found in your registry.
(steps 2-4 shown below)
<html>
<head>
<script src = "libs/system.js"></script>
<script src = "libs/bundle.js"></script>
<script>
Object.keys(System.registerRegistry).forEach((key) => System.import(key))
</script>
</head>
</html>
Upvotes: 2
Reputation: 450
I found this question when I needed to do something similar to bundle my Lambdas. The thing is, I only wanted to bundle my modules into single files with their imports included from my own code, not the node_modules.
I ended up using esbuild
to solve my problem:
esbuild ./src/lambda/** --outdir=./dist/lambda --bundle --platform=node --target=node18 --packages=external
Upvotes: 3
Reputation: 31632
This will be implemented in TypeScript 1.8. With that version the outFile option works when module is amd or system.
At this time the feature is available in the development version of Typescript. To install that run:
$ npm install -g typescript@next
For previous versions even if it's not obvious the module and the outFile options can not work together.
You can check this issue for more details.
If you want to output a single file with versions lower than 1.8 you can not use the module option in tsconfig.json. Instead you have to make namespaces using the module keyword.
Your tsconfig.json file should look like this:
{
"compilerOptions": {
"target": "ES5",
"removeComments": true,
"preserveConstEnums": true,
"outFile": "./build/build.js",
"sourceRoot": "./src/",
"rootDir": "./src/",
"sourceMap": true
}
}
Also your TS files should look like this:
module SomeModule {
export class RaceTrack {
constructor(private host: Element) {
host.appendChild(document.createElement("canvas"));
}
}
}
And instead of using the import statement you'll have to refer to the imports by namespace.
window.addEventListener("load", (ev: Event) => {
var racetrack = new SomeModule.RaceTrack(document.getElementById("content"));
});
Upvotes: 58
Reputation: 21510
You can do this with a custom tool called ncc, built and maintained by Vercel. Here's how they're using it in create-next-app:
ncc build ./index.ts -w -o dist/
Install it with yarn:
yarn add @vercel/ncc
Or npm:
npm install @vercel/ncc
Upvotes: 31
Reputation: 4096
If your code contains only regular Typescript, without modules (import/export) you just need to add parameter outfile
to your tsconfig.json
.
// tsconfig.json
{
"compilerOptions": {
"lib": ["es5", "es6", "dom"],
"rootDir": "./src/",
"outFile": "./build/build.js"
}
}
But this option have some limitations.
If you get this error:
Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'
Try "Option 2" below.
If you are using modules (import/export), you will need a module loader to run your compiled script in the browser.
When you compile to a single file (using outFile
), Typescript natively supports compiling to amd
and system
module loaders.
In tsconfig, you need to set module
to amd
or system
:
// tsconfig.json
{
"compilerOptions": {
"module": "AMD",
"lib": ["es5", "es6", "dom"],
"rootDir": "./src/",
"outFile": "./build/build.js"
}
}
If you choose AMD, you need to use the require.js
runtime. AMD requires an AMD loader, require.js is the most popular option (https://requirejs.org/).
If you choose System, you need to use the SystemJS module loader (https://github.com/systemjs/systemjs).
Probably, the best option is to use a module bundler / build tool, like Webpack.
Webpack will compile all your TypeScript files to a single JavaScript bundle.
So, you will use webpack
to compile, instead of tsc
.
First install webpack, webpack-cli
and ts-loader
:
npm install --save-dev webpack webpack-cli typescript ts-loader
If you are using webpack with Typescript, it's best to use module
with commonjs
:
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es5", "es6", "dom"],
"rootDir": "src"
}
}
Webpack webpack.config.js
example:
//webpack.config.js
const path = require('path');
module.exports = {
mode: "development",
devtool: "inline-source-map",
entry: {
main: "./src/YourEntryFile.ts",
},
output: {
path: path.resolve(__dirname, './build'),
filename: "[name]-bundle.js" // <--- Will be compiled to this single file
},
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader"
}
]
}
};
Now, to compile, instead of executing using tsc
command, use webpack
command.
package.json
example:
{
"name": "yourProject",
"version": "0.1.0",
"private": true,
"description": "",
"scripts": {
"build": "webpack" // <---- compile ts to a single file
},
"devDependencies": {
"ts-loader": "^8.0.2",
"typescript": "^3.9.7",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
}
}
Webpack's TypeScript Documentation
Lastly, compile everything (under watch mode preferably) with:
npx webpack -w
Upvotes: 90