@messman/ts-webpack-builder
v2.3.0
Published
A tool for building TypeScript libraries and applications.
Maintainers
Readme
ts-webpack-builder
An npm package used to build other npm packages or via TypeScript and webpack.
Note: This project is not intended for use by anyone other than the creator.
npm install --save-dev @messman/ts-webpack-builder
Why?
Why use webpack to create libraries? You could just use a tsconfig.json file and be done with it. But the problems with that include:
- You can't have a single output JS file unless you are using
AMDorSystemas themoduleproperty. Webpack allows us to create a single JS output (although we can't have a single output TypeScript declaration file - more on that below). - You don't get optimization, tree-shaking, etc.
- You can't run other plugins, like
babel.
Thus, this package was born. It's like many others, but I wanted to create one myself. If you want a package that's going to be better supported or more powerful, check out ts-engine.
Features
- Can run for both client (web) and server (node) libraries. (They require different bundling strategies.)
- Hides webpack config for libraries behind-the-scenes so it doesn't have to be added to every project.
- Optionally can run the code through babel (and also hides it behind the scenes so it doesn't have to be added to every project). (This hasn't been well-tested.)
- Includes a
watchsetting. - Can be imported and run from code or run through a CLI for direct builds from
package.json. - Creates UMD libraries.
Build
Build with npm start. That runs the webpack build (meta, right) to create this library, then runs the tsc command to build the cli.
Use
To use in a project, you can install (dev) or use npm link:
- In the root of this downloaded source, run
npm link. That installs this package in the npm global space for this machine. - In the project you want to use, run
npm link @messman/ts-webpack-builder. That finds the global installation and binds it into that project. Note, thets-webpack-builderwon't show up in thepackage.jsondependencies. That's just not hownpm linkworks. But it will show up innode_modules(symlink).
Once this tool is added to the consuming project, you can either create a script in that project to call into this tool (like a runner.js) or you can use the CLI.
See the test folder for more information on both. The CLI should be improved in the future to be more customizable / have better shortcuts.
In your package.json, to create a usable library:
"main": "dist/index.js",
"types": "dist/index.d.ts",projects that consume the output of your target project may need their tsconfig.json changed to
"moduleResolution": "Node"In order to resolve packages in the node_modules directory when using module imports.
CLI
The CLI exists in the cli folder. It is built separately from the rest of the code in src and is actually bound to the built code in dist folder (so that it only uses the types and doesn't try to transpile anything in src - that's also why it doesn't get put into dist after transpilation).
When installed in the target project, the CLI is accessible at ./node_modules/.bin/@messman/ts-webpack-builder. You can run it like that or call npx ts-webpack-builder. Or you can set up a custom command through package.json:
{
"scripts": {
"start-cli": "ts-webpack-builder",
},
}You can pass in any arguments there as well.
Notes on the CLI:
- The CLI does not require you to pass in an
absoluteRootproperty. - There is a CLI options to specify a path to a babel config file.
- The CLI will automatically look for a file in your project called
tswb.jsthat can contain build options. This file can specify one object of build options or a dictionary.
See the test area for examples.
Development
Typical steps are:
- Make a change, save, then call
npm startin the root of this project to do the webpack build and the CLI build. cd ../testto go into the test.- Run the tests (see the
testREADME)
There are some times where you may need to delete the ts-webpack-builder folder in node_modules in test, then re-link, like after you've installed something new.
This project uses a common tsconfig.json.
Future tasks:
- Add a test for babel config.
Babel
Use of babel is not tested. It probably doesn't work yet. The idea is as such:
- If using a script file to run the build, you can pass the babel config through
babelConfigas an object. - Through the CLI, you can provide the path to a babel config (which could be a JS or JSON file).
In both cases, you need to install your presets as dev dependencies in the consuming project - ts-webpack-builder does not have any.
TypeScript Declaration Files
Every time I create a library, I question why I can't bundle TypeScript Definition files like I bundle JavaScript files. Answer: because it's a huge hassle and not worth the time.
See TypeScript #4433
Many hours have been spent researching the possibilities of combining declaration files into a single output. Long story short, it's not possible unless you:
- do it yourself (like those that write their own definitions for
@types) - create a very specialized build library to handle it
- use one of the solutions out there (like
dts-bundle-generator) that comes with caveats
Why's it so difficult? When webpack combines into a single output file, it's because it's essentially wrapping the entire JS module environment. That's just not possible with declarations, which are more static. So the problems you run into include, for example, you wouldn't be able to name any types the same, because they will be flattened and override each other. Then on top of that, you wouldn't be able to handle the .map files that allow you to go directly to the source!
History
- 2.0.0: Upgrade to Webpack v5
