Search code examples
typescriptwebpackelectronboilerplate

Electron + Typescript + Webpack: Boilerplate Example


I don't know how to start the question, but the main problem is that I can't make the 3 technologies work together: Electron + Typescript + Webpack

I've encountered few boilerplates, but in them either the whole typescript is built with tsc (instead of Webpack), or only render-part is built with Webpack, and the main-process (main.js) part is written in pure js.

So I was wondering if anybody has or knows where to find a boilerplate project to start the new Electron + Typescript + Webpack project?

As far as I understand it should be configured to build separately main-process and render-process parts of the application (probably, their configs might be different).

Thanks in advance.


Solution

  • I have added a sample template/boilerplate on below link

    https://github.com/tarunlalwani/electron-webpack-typescript-boilerplate

    So the idea is to break the code in 3 folders

    src
    |-- common
    |-- main
    |-- renderer
    

    The code for the main electron process will go into main folder and for the UI/renderer will go into the renderer folder.

    Now you want to use TypeScript in both and have 2 webpack config, one for bundling the main and one for bundling the renderer.

    const path = require('path');
    
    console.log(__dirname);
    let common_config = {
      node: {
        __dirname: true
      },
      mode: process.env.ENV || 'development',
      module: {
        rules: [
          {
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: [
              /node_modules/,
               path.resolve(__dirname, "src/ui")
            ]
          }
        ]
      },
      resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
      },
    };
    
    module.exports = [
      Object.assign({}, common_config, {
        target: 'electron-main',
        entry: {
          renderrer: './src/main/index.ts',
        },
        output: {
          filename: '[name]-bundle.js',
          path: path.resolve(__dirname, 'src/main/dist')
        },
      }),
      Object.assign({}, common_config, {
        target: 'electron-renderer',
        entry: {
          ui: './src/renderer/index.ts',
        },
        output: {
          filename: '[name]-bundle.js',
          path: path.resolve(__dirname, 'src/renderer/dist')
        },
      })
    ]
    

    Another issue that one faces is that __dirname becomes / if do nothing about it. So we include below in our webpack config

      node: {
        __dirname: true
      },
    

    This make sure that a relative path is available. Now we can use os.cwd() in dev environment and use process.resourcePath in production. See below thread for more details

    How to run and pack external executable using Electron?

    The target for both the webpack config needs to be different. So for main we use electron-main and for renderer we use electron-renderer

    The tsconfig.json needs to be different for both main and renderer and should excluded each other. So we use

    renderer/tsconfig.json

    {
        "compileOnSave": false,
        "compilerOptions": {
            "target": "es2015",
            "moduleResolution": "node",
            "pretty": true,
            "newLine": "LF",
            "allowSyntheticDefaultImports": true,
            "strict": true,
            "noUnusedLocals": true,
            "noUnusedParameters": true,
            "sourceMap": true,
            "skipLibCheck": true,
            "allowJs": true,
            "jsx": "preserve"
        },
        "exclude": [
          "node_modules",
          "src/main"
        ]
    }
    

    main/tsconfig.json

    {
        "compileOnSave": false,
        "compilerOptions": {
            "target": "es2015",
            "moduleResolution": "node",
            "pretty": true,
            "newLine": "LF",
            "allowSyntheticDefaultImports": true,
            "strict": true,
            "noUnusedLocals": true,
            "noUnusedParameters": true,
            "sourceMap": true,
            "skipLibCheck": true,
            "allowJs": true,
            "jsx": "preserve"
        },
        "exclude": [
          "node_modules",
          "src/renderer"
        ]
    }
    

    The final main thing is your package.json, which is below

    {
      "name": "boilerplate",
      "version": "1.0.0",
      "main": "src/main/dist/renderrer-bundle.js",
      "license": "MIT",
      "scripts": {
        "start": "npm-run-all build run-electron",
        "build": "webpack --config webpack.config.js",
        "run-electron": "electron ."
      },
      "dependencies": {
        "electron": "^1.8.2",
        "jquery": "^3.3.1",
        "typescript": "^2.7.2",
        "webpack": "^4.0.1"
      },
      "devDependencies": {
        "@types/electron": "^1.6.10",
        "@types/jquery": "^3.3.0",
        "@types/node": "^9.4.6",
        "html-webpack-plugin": "^2.30.1",
        "npm-run-all": "^4.1.2",
        "ts-loader": "^4.0.0",
        "tslint": "^5.9.1",
        "webpack-cli": "^2.0.9"
      }
    }
    

    This is should get your started and then you can add things link tslint, jslint as you go along