3

My goal is to import .ts file as it is instead of specifying the file type as .js e.g import {acccessRights} from "utils/accessRights".

My expected result: I can import a method from other file without specifying the file type.

My actual result: It throws error GET http://127.0.0.1:5501/build/lights/switchLights net::ERR_ABORTED 404 (Not Found).

Temporary solution: specify the file type as .js e.g import { switchLights } from "lights/switchLights.js". However, the jest will break because it does not find the .js file.

part of index.html

<body>
  <script type="module" src="app.js"></script>
</body>

part of app.ts

import { User } from "./utils/accessRights";
import { switchLights } from "./lights/switchLights";

utils/accessRights.ts

export interface User {
  role: string;
}

export function userIsAdmin(user: User): boolean {
  return user.role === "admin";
}

lights/switchLights.ts

import {User, userIsAdmin} from "../utils/accessRights";

let lightsCondition: boolean = false;

function switchLightsRender() {
  document.getElementById("lightsCondition").innerHTML = lightsCondition ? "ON" : "OFF";;
  document.getElementById("lightsButton").innerHTML = `Lights ${!lightsCondition ? "ON" : "OFF"}`;
}

export function switchLights(user: User) {
  if (!userIsAdmin(user)) return false;
  lightsCondition = !lightsCondition;
  switchLightsRender();
  return true;
}

These are the jest files for the unit tests.

test/utils/accessRights.test.ts

import {userIsAdmin, User} from "../../src/utils/accessRights";

export let userTest: User = { role: "admin" }

test('user is admin', () => {
  expect(userIsAdmin(userTest)).toBe(true);
})

test/lights/switchLights.ts

import {userTest} from "../utils/accessRights.test";
import {switchLights} from "../../src/lights/switchLights";

test("lights switched ON/OFF", () => {
  let lightsConditionRef = document.createElement("span");
  lightsConditionRef.setAttribute("id","lightsCondition");
  document.body.appendChild(lightsConditionRef);

  let lightsButtonRef = document.createElement("button")
  lightsButtonRef.setAttribute("id","lightsButton");
  document.body.appendChild(lightsButtonRef);
  
  expect(switchLights(userTest)).toBe(true);
})

This is one of the transpiled .ts file to a .js file

The issue is that the auto generated code does not specify the file type in the import

My expected result:

import { userIsAdmin } from "../utils/accessRights.js";

My actual result:

import { userIsAdmin } from "../utils/accessRights";

This is the auto generated file.

build/lights/switchLight.js

import { userIsAdmin } from "../utils/accessRights";
var lightsCondition = false;
function switchLightsRender() {
    var lightsConditionRef = document.getElementById("lightsCondition");
    if (lightsConditionRef !== null)
        lightsConditionRef.innerHTML = lightsCondition ? "ON" : "OFF";
    ;
    var lightsButtonRef = document.getElementById("lightsButton");
    if (lightsButtonRef !== null)
        lightsButtonRef.innerHTML = "Lights " + (!lightsCondition ? "ON" : "OFF");
}
export function switchLights(user) {
    if (!userIsAdmin(user))
        return false;
    lightsCondition = !lightsCondition;
    switchLightsRender();
    return true;
}
13
  • Are you using a transpiler/compiler to convert the typescript to JS? Commented May 13, 2021 at 10:30
  • @evolutionxbox yes. I use "module": "es2015" in the tsconfig.json Commented May 13, 2021 at 10:32
  • Sorry, I meant do you use a tool like, parcel, webpack, etc? The reason I ask is because you can't import a typescript module into a native JS module (native meaning not transpiled) and expect it to work Commented May 13, 2021 at 10:33
  • "However, the jest will break because it does not find the .js file." Could you please include this file, and the thrown error in the question? Commented May 13, 2021 at 10:33
  • 1
    @evolutionxbox No, I use Live Server extension from the VS Code to run the index.html, and I also run tsc --watch to transpile it automatically. Commented May 13, 2021 at 10:36

1 Answer 1

1

This is your issue: How to make TypeScript output valid ES6 module import statements?

Solution:

Use a bundler. I'd suggest using parcel for now, mostly because it doesn't require any setup.

If you need to configure a lot of things and have edge cases, I would recommend using webpack.

Installing parcel

  1. npm i -D parcel
  2. Actually change the import in your HTML file form app.js to app.ts (or whatever your file is called).
  3. Add an npm script to develop:
"scripts": {
  "serve": "parcel index.html"
},
  1. run npm run serve

This will host a server for you (URL in the terminal) and recompile if you change anything.

Parcel Documentation(Getting Started)

Sign up to request clarification or add additional context in comments.

8 Comments

What about using tsc the typescript compiler? That's what the OP is already using
@evolutionxbox Have you looked at the link I put at the top of my answer? As far as I understood it, that's not possible.
@Elias I use parcel with tsc as well. It works. I have no idea why. I still use .js in the script tag <script src="build/app.js"></script> and use tsc --watch to compile.
@kidfrom You don't have to use tsc --watch to compile. parcel will do that for you
@Elias am I using it the wrong way?as you said it's not possible.
|

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.