Reputation: 73
I want to import a submodule from a ts file into my project. The problem is that the output file includes the entire imported file and not only the imported object.
I have an example.ts file with several exports:
export enum e1{a, b}
export enum e2{c, d}
export class exampleclass
{
static f()
{
return 1;
}
}
Update: I have another file - exampleUser.ts which imports parts from example.ts.
import {e2} from "./example";
export enum eu1{a, b}
export enum eu2{c, d}
I have a 3rd file - main.ts which imports parts from exampleUser.ts. When I use the following import
import {eu2} from "./exampleUser";
and transpile the project (using webpack) the bundled output contains un-used parts of code from exampleUser.ts and from example.ts.
tsconfig.json:
{
"compilerOptions": {
"target": "es3",
"module": "es6",
"allowJs": true,
"checkJs": false,
"sourceMap": true,
"removeComments": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
}
}
package.json:
{
"sideEffects": false
"devDependencies": {
"concurrently": "^3.6.0",
"ts-loader": "^4.3.0",
"typescript": "^2.8.3",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3"
},
}
webpack.prod.js:
{
mode: 'production',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
optimization: {
minimize: true, // Control if the output is monified (and uglified) or not
usedExports: true
},
}
package-lock.json:
{
"ts-loader": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.3.0.tgz",
"integrity": "sha512-+zduqQJaeouVrGY3y6+nUG7+OE1+Q7slGCHsiQM/aITCEZ0og3GxrJVsnjM5QcWvOcu9C4VR5dP+egIyT+sNNg==",
"dev": true,
"requires": {
"chalk": "2.4.1",
"enhanced-resolve": "4.0.0",
"loader-utils": "1.1.0",
"micromatch": "3.1.10",
"semver": "5.5.0"
}
}
}
Is it possible to import only the relevant code?
Upvotes: 0
Views: 1139
Reputation: 12755
Things you asking about is a Tree shaking. Typescript does not do it out of the box. You use webpack which can do that. Please see how to set up it here Tree shaking
I guess it would be enough to set mode: 'production'
and webpack will optimize your output
UPD:
After some discuss it was found out: with typescript's target lower than "es2015" class will be compiled to regular function. Functions could have side effect via closures, so it could be unsafe to remove "unused code" and webpack includes everything "just in case"
To tell webpack that function is safe to delete compiler could put #__PURE__
comment near the function but Typescript puts @class
instead.
We can write simple webpack loader to replace @class
to #__PURE__
. It is a little dirty but workable solution.
module.exports = function(content) {
return content.replace(/\/\*\* @class \*\//g, '\n /*#__PURE__*/ \n');
};
The repo with proposed loader
On my projects I prefer the following solution: typescript => ESNext javascript (ts-loader) => Es5 (babel-loader) Typescript here is for type-checking, while babel take care about es5
Upvotes: 1