fuse-box / fuse-box

A blazing fast js bundler/loader with a comprehensive API :fire:
http://fuse-box.org
MIT License
4k stars 237 forks source link

Transpiling external modules #1277

Closed belemaire closed 6 years ago

belemaire commented 6 years ago

This is not really an issue, but more of a question,

We are working on a project that is composed of different modules and are using lerna/yarn workspaces to link them together during development.

These modules are all written in TypeScript. We have a command line client that is relying on these modules (performing some kind of orchestration), and we are starting to write a UI desktop client using Electron / React and Fusebox for the heavy lifting ;)

We are not especially trying to integrate the UI desktop in our lerna/yarn workspace workflow. Actually it is a separate project for now. Here is a simplified directory structure to illustrate :

UI/
├── src/
│   ├── index.ts
├── fuse.ts
├── tsconfig.json
module-A/
├── src/
│   ├── index.ts
├── dist/
│   ├── index.js
module-B/
├── src/
│   ├── index.ts
├── dist/
│   ├── index.js
tsconfig.json
lerna.json

module-A might have a dependency on module-B, and UI might have dependencies on module-A and module-B let's say.

Up until now, with TypeScript we are using the baseUrl and path with tsconfig-paths plugin. We define the paths in compilerOptions as "module-*":["module-*/src"]. This way if we do import * from module-A in a source file in module-B, the module loading will properly happen. This is very helpful also for development as we are running our command line client with ts-node and all files are properly transpiled on the fly.

My question is, how can we make fusebox work with these external modules, and ideally enable HMR for them as well. I tried to use the baseUrl/path combo in the UI/tsconfig.json as we did for our command line client, without luck. Then I tried the alias way in fuse config, but it seems like doing this way, properly resolve the source file path, but does not perform transpilation (maybe expecting pre-transpiled code).

Isn't it possible to do import * from 'module-A' in UI/src/index.ts and make it work so that fuse will properly transpile the code of module-A (knowing that module-A might also import some stuff from module-B ... right now the baseUrl/path of root tsconfig is taking care of mapping).

Or should we try something a bit more complex, like pre-transpiling all module-* prior to launching FuseBox dev ?

Just trying to find the ideal dev workflow here, even if it makes config more complex.

Still looking into it, trying out different things, but thought I could also ask here in //.

Thanks !

EDIT : Seems related jn some way to https://github.com/fuse-box/fuse-box/issues/563 . In our case though we are using tsconfig-path during development to transpile our modules (our CLI dev entry point is using ts-node to transpile modules on the fly). So sounds like issue might be about support of tsconfig-path with Fuse in some way ?

EDIT 2 : Maybe could just go first with a Sparky task to run tsc for all modules (as we do for distrib) before bundling as I was able to make it properly work when the modules code was pre-transpiled (loading the module from their dist directories). But would have to relaunch bundler / dev server every time a change is made in one of the source of these modules (unless there is a way to handle this more properly). Starting playing with FuseBox very recently, so still have to figure things out ;)

nchanged commented 6 years ago

@belemaire Hi. Please install the latest fuse-box@next. Then there is are the steps to achieve what you want.

In your parent tsconfig (which is next to lerna.json) set the following

 "baseUrl": ".",

This will make FuseBox map all of the parent folders automatically. Then your homeDir should point to where lerna.json is. I would recommend creating a folder for that. As in src/

So when you launch the app using the latest @next you will see something like this in the logs

 → Applying automatic alias based on baseUrl in tsconfig.json
  →
        module-a => "~/module-a"
        module-b => "~/module-b"

Then anywhere in your source code, you will be able to do the following.

import * as a from "module-a"

HMR will work, and of course, that's the perfect workflow for development. Another option is to map your modules manually, which gives you more control over which modules are "globally" available but requires manual work. You could also extend it, and add additional aliases on top of what FuseBox already does automatically.

FuseBox.init({
   alias : {
       "module-a" : "~/module-a"
   }
})

You will get 1 ginormous bundle in the end, but if you keep one homeDir everything should be working smoothly.

I hope that helps.

vegarringdal commented 6 years ago

@nchanged

Ive tried this (and it works before next also:

tsconfig

 "baseUrl": "./",
    "paths": {
      "aurelia-v-grid": [
          "./src/aurelia-v-grid" //<-I_would_like_to_use_name_plugin_here "plugin"
      ]
    }
alias: { "aurelia-v-grid": "~/src/aurelia-v-grid/" }, // <- why cant I have `~/plugin` <-is that a bug ?

But if I want to have my package "aurleia-v-grid" in a more general folder called plugin the alias fails

nchanged commented 6 years ago

@vegarringdal yeah it's the same. @next just automates it ;-)

vegarringdal commented 6 years ago

@nchanged is it possible for me to use a folder with another name? "module" point to folder "test"

vegarringdal commented 6 years ago

because I can do that with tsconfig and path, just alias in fusebox wont be able to find module after

belemaire commented 6 years ago

Thanks much @nchanged :clap: I went down the road of manually using alias instead of going with fusebox@next. Before opening this issue I tried different ways, including using alias but without any success. Seems like in the end it was just related to the homeDir pointing to the src directory of the ui project instead of pointing one directory up to where all of the modules are located. Works like a charm now with HMR :tada: ! As you're saying ... megabundle but hey it's just for dev env so that's OK :) Thanks again, closing this issue now !

SephReed commented 5 years ago

Oh man. I'm so tired right now, and just want to enjoy a personal project. Why exactly can't I just import a path with "../" in it? Is this not something that could be automated?

nchanged commented 5 years ago

Yes you can, please try v4 all the issues are resolved there