10

I have a folder structure for a Node.js /w Angular.js project with some files like so (from project root):

frontend
  frontend-file1.ts
  frontend-file2.ts

backend
  backend-file1.ts
  backend-file2.ts

I use a TypeScript compiler along with many other gulp plugins to compile this into a build folder like so (notice how frontend files get placed into public):

build
  backend-file1.js
  backend-file2.js

  public
    frontend-file1.js
    frontend-file2.js

In the source folders, I use ES6/TypeScript import statements to import files.

Example: backend-file1.ts

import './backend-file2';

Situation

I've written some custom utility functions that should be used by both backend and frontend. I don't want to repeat the same functions in both folders, since this is prone to errors and is double work.

I've considered creating a shared folder at the project root amongs the frontend and backend folders, but I can't import files in the browser that go up further than the index.html file, which is in the frontend folder.

Question

How would I be able to write a TypeScript file once and be able to import this file in both frontend and backend folders?

3 Answers 3

3

I would just structure the code like this:

- src/
   - server/
   - client/
   - shared/

You can place all your shared libraries into shared directory then import/require them from your server or client source files:

import '../shared/library'
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer @lxe. However, the problem still persists, since from the index.html file in client, I will not be able to import files to "go up beyond the root", which is the client folder. I would not be able to access scripts from shared. I guess I could consider compiling the shared folder into both frontend and backend folder in the build? What do you think?
@Nicky assumed you are compiling your clientside scripts into a single file via --out bundle.js, which makes the location of the source imports irrelevant.
I see, and I do this, but only in production. For development, every file in compiled one:one in the build folder. Any suggestions for that situation?
1

To extend the already given answer for outFile case I will show my way of dealing with class sharing in case when you cant or do not want to use webpack/browserify/outFile options.

The structure looks similar

-client
    index.html
    app.ts
-server
    service.ts
-common
    helper.ts
-dist
    -client
        -index.html
        -lib
            -client
                app.js
            -common
                helper.js
    -server
        service.js
    -common
        helper.js

The idea is how you build the dist folder with the results of your build. I do this with gulp tasks and by having the structure above it allows me to reuse components both server and client side from the common library.

Note. To work at client side do not forget to setup base url for systemjs in index.html:

    System.config({
        baseURL: './lib'
    });

    System.defaultJSExtensions = true;

Hope this helps.

Comments

1

I wanted to share what I've done so that others have the same option. I felt the other options which are cleaner required a lot more work, and since this is a personal project I set it up in a simpler but more crude way.

Basically I wanted to use symlinks so that I could edit it from either location without issue and without making too many changes to the current project structure. I'm also lucky that I don't need to support Windows for this.

I already had a single repo with a React app in the fe folder and the backend server in be, both using TypeScript. Here's my resulting folder setup:

be/
  src/
    shared -> ../../fe/src/shared
fe/
  src/
    shared/

I'll note that React does not support symlinks (IIRC it's because webpack does not support symlinks) and so the "real" folder should be in the frontend.

I also wanted this to work without manual setup, and so I made an extra script in package.json which makes sure the symlink is already set up. It also creates a broken symlink if the symlink is already there, but again, this is for a personal project and I'm okay with it. (Happy to update it if someone has a better understanding of ln than I do.) In the backend's package.json:

"prebuild": "ln -f -s ../../fe/src/shared src/shared",
"build": "tsc",

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.