Skip to main content

Setting up your typescript project

A typical Coinweb project written in Typescript will typically use a combination of the wallet library and one or more contract modules. As contract modules are standalone packages, a project setup will easily consist of multiple packages, in which case using tools like yarn workspaces or lerna might be appropriate.

We will use the following example as our default project, showing a combination of an end-user project and using on-chain smart contracts.

There is a main-project which consists of normal typescript (maybe a React project), and as dependencies it uses two other contract modules: contract-module-a, and contract-module-b.

plantuml

plantuml

Setting up a Yarn Workspace with Dependencies

  1. Initialize a new project:

    mkdir my-workspace
    cd my-workspace
    yarn init
  2. Modify your package.json to add the workspaces field: This defines which directories are considered Yarn workspaces.

    {
    "name": "my-workspace",
    "private": true,
    "workspaces": ["packages/*"],
    "nohoist": ["**"]
    }

    The nohoist option is currently required in order to be compatible with the cweb-tool audit command.

  3. Create the packages directory and your individual packages:

foreach ($dir in "main-project", "contract-module-a", "contract-module-b") {
mkdir $dir
}
  1. Now your directory structure should look like this:

    my-workspace/

    ├── packages/
    │ ├── main-project/
    │ ├── contract-module-a/
    │ └── contract-module-b/

    └── package.json
  2. Initialize each package: Navigate to each package directory and initialize it.

    cd main-project
    yarn init
    cd ../contract-module-a
    yarn init
    cd ../contract-module-b
    yarn init
  3. Adding Dependencies:

    Inside main-project, contract-module-a, and contract-module-b:

cd main-project
yarn add @coinweb/wallet-lib
yarn add @coinweb/cweb-tool --dev

For TypeScript development:

  1. Use tsc --init inside each package to generate a tsconfig.json.
  2. Configure the tsconfig.json based on your needs.
  3. Use tools like tslint or eslint with TypeScript plugins for linting.
  4. Follow the instructions in the next section to setup webpack to bundle your TypeScript code.

Webpack Configuration:

Create a file named webpack.config.js in the roots of contract-module-a and in contract-module-b:

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = (env, argv) => {
const isProduction = argv.mode === 'production';

return {
entry: './src/main.ts',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'onchain_lib'),
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
optimization: {
minimize: isProduction,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
},
};
};

tsconfig.json settings:

For the contract modules, ensure your tsconfig.json has at least the following settings:

{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"target": "ES5"
}
}

package.json scripts:

In your contract-module-a/package.json, and contract-module-b/package.json files, add the following to the scripts section:

"scripts": {
"build": "webpack --mode production",
"dev": "webpack --mode development",
"postinstall": "cweb-tool audit",
}

With these scripts:

  • Running yarn build will generate a production-ready, minified output at onchain_lib/main.js.

  • Running yarn dev will generate a development version of the output without minification.

  • Running yarn add ... will audit whether the new dependency works for the contract module.

By default, the production mode in Webpack will enable various optimizations including minification. The TerserPlugin will take care of the minification, and with the configuration provided, it will also drop all console logs. Adjust as per your needs!