10

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.

Mark Dolbyrev
  • 1,887
  • 1
  • 17
  • 24
  • 1
    Are you fixed on Webpack? If not you might want to try [FuseBox](https://fuse-box.org/). I find it much easier to use than Webpack, I don't know if its more limited, but it was always enough for my needs. They also have an Electron seed on GitHub. – Tao Feb 27 '18 at 12:12
  • Do you need a example one which you can then expand? Boiler plates have lot of things setup like testing, jslint and all. I was able to work a simple enough template for you with TS+Webpack+Electron for both main and renderer process and its working great. If that much works for you, I will push it to git and share – Tarun Lalwani Feb 28 '18 at 15:49
  • @TarunLalwani, sorry, I thought about the term "boilerplate" as a template here. What you described is exactly what I'm looking for (just a very very simple project which can be used as a start point for development). So yes, it would be great, if you provide access to your solution. – Mark Dolbyrev Feb 28 '18 at 19:40
  • @MarkDolbyrev, uploaded it here, https://github.com/tarunlalwani/electron-webpack-typescript-boilerplate. Check it out and let me know if that solves your purpose then I will add few details and post and answer – Tarun Lalwani Feb 28 '18 at 20:27
  • @TarunLalwani, checked your project, it's exactly what I was looking for. Please, add your answer to my question. – Mark Dolbyrev Mar 01 '18 at 15:07

3 Answers3

28

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

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • 2
    Thanks for the example, very helpful. What is the advantage to keeping two distinct webpack configs and typescript configs for the main electron process and the renderer? – Bill DeRose May 31 '18 at 21:37
  • 2
    @BillDeRose, this is because the renderer javascript is running in browser and electron is running in nodejs. They have two different code bundles, that is why two different configs. – Tarun Lalwani Jun 01 '18 at 07:06
  • @TarunLalwani Would have been a perfect solution if it had HMR. – netlander Jul 11 '18 at 12:00
  • @TarunLalwani Nice solution, is it possible to do something similar using a react-scripts-ts npm where webpack.config.js is not easily accessible without ejecting. – Elarys Aug 21 '18 at 04:47
3

Tarun Lalwani's answer was pretty great, but I wanted to offer a modern alternative to anyone who stumbles across this page.

https://github.com/hellosoftware-io/electron-typescript-react-mui

It uses electron 15, typescript, and webpack 5. It also supports live reloading as requested by netlander.

My strategy was to setup the file structure like this

static
src
|-- main
|-- renderer

The static folder holds images, main holds electron content, and renderer holds the js (currently built with react).

I'm also using just one tsconfig and two webpack configs to try and simply things a bit.

I hope this helps anyone who stumbles across this post :)

Xhale
  • 31
  • 3
0

Been looking for similar here for React & TypeScript but with latest Electron v16 and Devtools integration. Using this boilerplate tool for now, specially for Hot Reloading assets and modules (HMR). Not a fan of LESS stylesheet, would prefer SASS which can be easily changed via provided webpack configs.

https://github.com/codesbiome/electron-react-webpack-typescript-2021

(Seems like they even updated it recently with more changes to use a custom Window Titlebar and File menu etc)

Wooly
  • 1
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/30794435) – Serge P Jan 16 '22 at 04:55