I have 2 typescript projects, 1 depends on the other. I can generate the typescript declaration files by setting declaration: true in tsconfig (which would be applicable to both projects). I also set outDir to ./dist. I can see plenty of generated declaration files emitted to the dist folder.
I am also using webpack. But how do I get wepack to include all those declaration files in the bundle so that the client can consume it?
So my tsconfig looks like this:
{
compilerOptions: {
allowJs: true,
alwaysStrict: true,
esModuleInterop: true,
module: commonjs,
moduleResolution: Node,
noImplicitAny: true,
sourceMap: true,
strictNullChecks: true,
target: es5,
declaration: true,
outDir: ./dist,
types: [
mocha, node, ./dist/index.d.ts
],
lib: [
es5,
es2015,
es6,
dom
]
},
include: [
lib/**/*, tests/**/*
],
exclude: [
node_modules,
**/*.spec.ts
]
}
However, this is not working. The see the following error message:
ERROR in /Users/Plastikfan/dev/github/js/jaxom/tsconfig.json
[tsl] ERROR
TS2688: Cannot find type definition file for './dist/index.d.ts'.
Actually, when I look at this:
types: [
mocha, node, ./dist/index.d.ts
],
this makes me concerned, because /dist/index.d.ts is an output of the webpack/typescript build process, so how can the build see its content at the beginning of the build process when presumably it would not exist. To me this doesnt seem right, so how do I declare that ./dist/index.d.ts are the declarations for the project?
Then once this is fixed, how does the typescript client consume the typescript/javascript package; ie I have another project (zenobia) also a typescript project, which needs to consume the typescript project from npm, so what do I need to do to get this to work properly? Jaxom is the source typescript project to be consumed and in it's index file, its exporting all the client facing declarations actually it looks like this:
index.ts:
export * from './types';
export * from './specService/spec-option-service.class';
export * from './converter/xpath-converter.class';
which is the same as the corresponding generated dist/index.d.ts
On the cosuming side (zenobia) I know I need some kind of triple slash directive and an import statement, but am going round in circles not getting it right.
The tsconfig in zenobia is the same as jaxom (as I show above).
The import on the client looks like this:
import * as Jaxom from 'jaxom';
so I would expect all the definitions exported to be available on Jaxom. This import should work because its typescript. If it was js, then this wouldn't work for Nodejs projects.
The documentation I have read is either ambiguous to me, or the explanation I require sits somewhere in between webpack and typescript with neither explaining the full integration properly or making assumptions.
In Jaxom, I have 2 webpack configs (1 for the production code and the other for the tests). This is the pattern I've used/am using for all my webpack/typescript projects.
production webpack config for Jaxom:
module.exports = env => {
const { getIfUtils } = require('webpack-config-utils');
const nodeExternals = require('webpack-node-externals');
const { ifProduction } = getIfUtils(env);
const mode = ifProduction('production', 'development');
console.log('>>> Jaxom Webpack Environment mode: ' + env.mode);
return {
entry: {
index: './lib/index.ts'
},
target: 'node',
externals: [nodeExternals()],
mode: mode,
module: {
rules: [
{
test: /.ts(x?)$/,
use: 'ts-loader'
},
{
test: /.json$/,
use: 'json-loader'
}
]
},
plugins: [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': 'production' }),
new webpack.BannerPlugin({
banner: '#!/usr/bin/env node',
raw: true
})
],
resolve: {
extensions: ['.ts', '.json']
},
watchOptions: {
ignored: /node_modules/
},
output: {
filename: 'jaxom-bundle.js',
sourceMapFilename: 'jaxom-bundle.js.map',
path: path.join(__dirname, 'dist'),
libraryTarget: 'commonjs'
}
};
};
And the webpack config for the tests
module.exports = {
devtool: 'source-map',
mode: 'development',
entry: ['./tests/all-tests-entry.js', './lib'],
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{
test: /.xml$/i,
use: 'raw-loader'
},
{ test: /.ts(x?)$/, loader: 'ts-loader' },
{ test: /.json$/, loader: 'json-loader' }
]
},
resolve: {
extensions: ['.ts', '.json']
},
watchOptions: {
ignored: /node_modules/
},
output: {
filename: 'jaxom-test-bundle.js',
sourceMapFilename: 'jaxom-test-bundle.js.map',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs'
}
};