albe-rosado / create-proton-app

No Configuration Starter Template for Proton Native Apps
MIT License
198 stars 23 forks source link

Typescript and HotReload Support #12

Open mjarmoc opened 6 years ago

mjarmoc commented 6 years ago

Hello,

I am trying to set up a project with typescript and hot reload support. I would really appreciate any guidelines :)

mischnic commented 6 years ago

For typescript see https://github.com/kusti8/proton-native/issues/122.

There is an experimental hot reload boilerplate at https://github.com/mischnic/proton-hot-boilerplate

khanhas commented 6 years ago

Here is a basic config for anyone interested in how to set up Typescript project with proton-native:

  1. Nodejs 10.3 and Yarn 1.7
  2. package.json
    {
    "name": "exampleApp",
    "version": "0.0.1",
    "scripts": {
    "start": "ts-node ./src/main.tsx",
    "build": "tsc",
    "build:watch": "tsc -w",
    "clean": "rd build /S /Q"
    },
    "dependencies": {
    "proton-native": "^1.1.5",
    "react": "^16.4.0",
    "ts-node": "^6.0.5"
    },
    "devDependencies": {
    "@types/node": "^10.0.4",
    "@types/proton-native": "^1.1.0",
    "@types/react": "^16.3.16",
    "typescript": "^2.9"
    }
    }
  3. ts-config.json

    {
    "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "jsx": "react",
    "lib": ["es2017"],
    "moduleResolution": "node",
    
    "outDir": "./build",
    
    "strict": true,
    "strictNullChecks": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    
    "allowSyntheticDefaultImports": true
    },
    "include": [
    "./src/*.tsx"
    ],
    "exclude": [
    "node_modules"
    ]
    }
  4. ./src/main.tsx
    
    import * as React from "react";
    import { render, Window, App, Box, Group, ProgressBar, Tab } from "proton-native";

class ExampleApp extends React.Component { public render() { return (

    );
}

}

render();

All examples in proton-native main page import React like this
```js
import React, { Component } from "react";

That import line means import React with its default export, and Typescript compiles anywhere use function in React namespace to react.default.functionName. But in React package, there is no default export so it always raise errors look like this:
TypeError: Cannot read property 'createElement' of undefined

It could be a bug of compiler so in this time, just import entire React's contents :

import * as React from "react";

and use Component with

React.Component
  1. Boot up our app! Install package:
    yarn

Run app:

yarn start

You can use npm but I feel more comfortable with yarn than npm so it's up to you.

While waiting for boilerplate to be finished, we have to close our app and run yarn start after every changes in code.

albe-rosado commented 6 years ago

I will play with this, tomorrow, I like Typescript too, thanks a lot

mischnic commented 6 years ago

While waiting for boilerplate to be finished, we have to close our app and run yarn start after every changes in code.

@albe-rosado Hot reloading will be fully functional with the next proton-native release and I think this would be a create addition to create-proton-app. I was thinking of:

A cli tool called proton-hot (welcoming suggestions for a better name) which is called like babel-node and hides all the complexity of the babel plugin, webpack, webpack-node-externals and node-hot-loader

EDIT: It's at https://github.com/mischnic/proton-hot-cli, so the change would literally be (untested):

diff --git a/src/createApp.js b/src/createApp.js
index 32bc5ff..434bc18 100644
--- a/src/createApp.js
+++ b/src/createApp.js
@@ -44,6 +44,7 @@ const createApp = function(projectDir) {
     scripts: {
       "start": "node_modules/.bin/babel-node index.js",
       "build": "node_modules/.bin/babel index.js -d bin/",
+      "dev": "proton-hot-cli index.js"
       "pack": "electron-builder --dir",
       "dist": "electron-builder"
     },
@@ -52,6 +53,7 @@ const createApp = function(projectDir) {
      },
     devDependencies: {
         "electron-builder": "latest",
+        "proton-hot-cli": "latest"
         "babel-cli": "latest",
         "babel-preset-env": "latest",
         "babel-preset-stage-0": "latest",

The default output directory is build.

albe-rosado commented 6 years ago

Cool, will start playing with that, I think the name is fine.

albe-rosado commented 6 years ago

@mischnic I tried out and got this error, any idea? I'm on Windows 10, Node v8.11.3. thanks a lot!

The above error occurred in the <Example> component:
    in Example (created by Wrapper)
    in Wrapper

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
The above error occurred in the <Wrapper> component:
    in Wrapper

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
[HMR] Ignored an error while updating module ./index.js (self-accept-errored)
[HMR] TypeError: Cannot read property 'setChild' of undefined
    at Root.removeChild (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\proton-native\bin\components\DesktopComponent.js:83:36)
    at removeChildFromContainer (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\proton-native\bin\reconciler\index.js:82:20)    at unmountHostComponents (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:6816:9))    at commitDeletion (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:6863:5)      )    at commitAllHostEffects (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:7445:11js:1793:10):11)    at Object.invokeGuardedCallback$1 (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.9)velopment.js:1793:10)                                                                                                                             .js:1938:2    at invokeGuardedCallback (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development    at Object.invokeGuardedCallback$1 (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:1793:10)                                                                                                                           34)    at invokeGuardedCallback (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:1938:29)    at commitRoot (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:7595:7)    at completeRoot (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:8645:34)    at performWorkOnRoot (C:\Users\snow\Documents\OSS\create-proton-app\sampl\node_modules\react-reconciler\cjs\react-reconciler.development.js:8589:9)[HMR] Ignored an update to unaccepted module ./index.js[HMR] The following modules couldn't be hot updated: (They would need restart the server!)[HMR]  - ./index.js
mischnic commented 6 years ago

Yes, this is what I meant by "Hot reloading will be fully functional with the next proton-native release". It's already fixed but not released yet: https://github.com/kusti8/proton-native/pull/164.

So for now, you can't change the main index.js file, only imported modules like app.js.

albe-rosado commented 6 years ago

@mischnic I know, I just wanted to make sure you are aware of this problem.

AnthoniG commented 6 years ago

@khanhas Thanks. That worked perfectly. Not really in need of auto-reload type at the moment so I can just start and stop the app.