Typescript compile with imports - javascript

So I have two files: a.ts and b.ts. b exports something for a to use. The TypeScript compiler handles this fine, but refuses to create valid output for a browser. Example:
import { test } from "./b";
console.log(test);
b.ts
export const test = "quest";
and now I try compiling it:
$ tsc --lib dom,es2018 --target ES2018 --out test.js a.ts b.ts
b.ts:1:1 - error TS6131: Cannot compile modules using option 'out' unless the '--module' flag is 'amd' or 'system'.
1 export const test = "quest";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 1 error.
hm, weird. Okay, let's try using --module. If I use amd a browser that loads test.js will tell me: ReferenceError: define is not defined. If I try system it says: ReferenceError: System is not defined.
Okay, that's not working. Let's try without setting a single output file with --out. That gives me:
SyntaxError: import declarations may only appear at top level of a module a.js:1
SyntaxError: export declarations may only appear at top level of a module b.js:1
So based on this, it seems like my only options for using typescript are:
Put all code in a single file
Use an external library like require.js or webpack
Learn what a module is and if/how it can be used in a browser
Or am I missing something? How do I compile Typescript using imports without adding libraries/modules ?
TypeScript version: 3.8.3

Syntax error
please correct this
export const test = "quest";
to
export test = "quest";
No need to add any const here while exporting

Related

webpack encore fails when importing enum from node_modules

I'm trying to use some enum from a library I made in another project.
The library is made with Vue and typescript, bundled with rollup, the project is made Synfony, and the front with Vue and typescript too, builded with Webpack Encore.
The library is a dependency from my project, so I try to import the enum like this:
import { MyEnum } from 'myLibrary/src/enum/MyEnum';
And the enum looks like this
// node_modules/myLibrary/src/enum/MyEnum.ts
export enum MyEnum {
One = 'one',
Two = 'two',
Three = 'three'
}
But when I build I got this error (with Symfony's Webpack Encore):
ERROR Failed to compile with 1 errors 4:37:05 PM
Error loading ./node_modules/myLibrary/src/enum/MyEnum.ts
FIX To process TypeScript files:
1. Add Encore.enableTypeScriptLoader() to your webpack.config.js file.
I obviously already added enableTypeScriptLoader() in webpack.config.js, and I don't know how to solve this.
If I create the same enum file into my project and import it, it works, but I have to keep it in my library and I don't want to duplicate code. And I import interfaces from the same library the same way, and it works fine.
I tried things that don't work :
export const enum kinda work, but I get the TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query. error, and I have to redeclare the enum in another object to use it in my template :/
export declare enum but still get the Add Encore.enableTypeScriptLoader() error
Any idea how to solve this?
EDIT
I have another error message in my browser that add some information:
Module parse failed: Unexpected token (4:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export enum MyEnum {
| One = 'one',
| Two = 'two'
I also test to import the same enum from the same library in a fresh project made with Vue Cli, and I have no error.
I'm pretty sure the issue come from Webpack Encore.
Solution found, some details in this Webpack Encore's issue : https://github.com/symfony/webpack-encore/issues/1060
And here's the fix :
1/ Add allowTsInNodeModules in enableTypeScriptLoader options:
Encore.enableTypeScriptLoader((options) => {
options.allowTsInNodeModules = true;
});
2/ Update rule to change exclude option that excludes node_modules, and exclude node_modules but my own modules (where #myCompany is the folder in node_modules where my own modules are.
Encore.configureLoaderRule('typescript', (rule) => {
rule.exclude = /node_modules\/(?!#myCompany)/;
});
This generates a warning when compiling, but for now it's the only way I found to fix this.

Node js SyntaxError: Unexpected token 'export'

I'm having the following error in the console when I try to run my api written in node js.
Can you tell me which is the problem.
Importing is generally done at the top of your files and looks like this:
import User, {schema} from './model.js'
Exporting is generally done at the bottom of your files and looks like this:
module.exports = {User, schema}
Ant the specific reason why you get the error is because export is not used that way.
Here is a direct quote from Web Docs:
export DefaultExport from 'bar.js'; // Invalid
You are using ES6 syntax.
Node.js uses common.js syntax
You can use module.export syntax or you can use babel npm package for translate ES6 syntax to common.js syntax
If you want to include a structure you have built, you need to use import.
If you want to export a structure that you have edited, you need to use export.

Import ES6 module from http url in Typescript

I am writing an ES6 module which depends on the other ES6 module specified with http url like this:
import { el, mount } from "https://cdnjs.cloudflare.com/ajax/libs/redom/3.26.0/redom.es.js";
const pElem = el("p") // definitely works in Javascript
When I tried to translate my module in Typescript, I got this error:
Cannot find module 'https://cdnjs.cloudflare.com/ajax/libs/redom/3.26.0/redom.es.js' or its corresponding type declarations.
I'm using ts-watch npm module to compile Typescript, and it works fine unless I don't use the import from https://....
I also know that if I tried to import npm module (e.g. import {el} from "redom") it works as well. But what I am writing is a module for web browser, not that of npm. With this reason, using webpack is not an option.
Thanks to #acrazing's comment, I managed to resolve this problem. Here's how:
In a new ts file:
declare module 'https://*'
This mutes the error that Typescript compiler attempts to read type declaration.
If you want to access type declaration as a node dependency, paste this in a new ts file:
declare module 'https://cdnjs.cloudflare.com/ajax/libs/redom/3.26.0/redom.es.js' {
export * from 'redom'
}
and add redom dependency in package.json
"dependencies": {
"redom": "3.26.0",
...
},
Then, type declaration is read from local ./node_modules directory, VSCode recognizes the types as well.
declare module 'https://*' somehow doesn't work for me so I simply ignore it.
// #ts-ignore Import module
import { Foo } from "https://example.com/foo.ts";
// Now you can use Foo (considered any)

How to import nodejs module "module" via es6 import to create "require" function with "createRequire" in order to use node's "require"?

I am writing a JavaScript es6 module which contains "Mocha" test-cases which test a JavaScript es6 module containing the actual functionality of my app.
I am trying to import nodejs module "module" via es6 import like so:
import { createRequire } from 'module';
Next I create a "require" function by calling "createRequire":
const require = createRequire(import.meta.url);
Afterwards I try to use "require" to import nodejs modules:
const chai = require('chai');
const assert = chai.assert;
I put that all together in a HTML file, started a web-server and opened the HTML file in the browser.
Unfortunately, the first line gives me an error in the console of the Browser Firefox:
TypeError: Error resolving module specifier: module
The browser Chromium gives me the following error message:
Uncaught TypeError: Failed to resolve module specifier "module". Relative references must start with either "/", "./", or "../".
Actually, giving relative references is not working either:
I installed the nodejs module "module" (npm install module) and used a relative path to that module. Unfortunately, the browser does not know how to load the module because no concrete entrypoint is given.
I just tried stick to the manual but had no luck:
https://nodejs.org/api/modules.html#modules_module_createrequire_filename
What do you think? How should I change my code so that this works?
Many thanks in advance for your valuable advice.
I hope you've installed the module using 'npm install module' command, try using commonJS pattern and include the module in the following way
const { createRequire } = require('module');
require() is used to load files in node, and module is a node module.
These things don't exist in browsers.
You do these things, and running mocha tests in node. There should be no browser, just a command line.

Typescript compiler "cannot find module" when using Webpack require for CSS/image assets

I am writing vanilla Javascript but using the Typescript compiler's checkJs option to do type checking in VSCode. I have Webpack set up to load various asset types (CSS, images, etc), which works fine for builds, but Code is treating these statements as an error. For example, in this code
require("bootstrap");
require("bootstrap/dist/css/bootstrap.css");
var img = require("../img/image.png");
the first line is fine but the next two both show an error under the (string) argument to require(), with the tooltip "Cannot find module (name)".
I have installed #types/webpack and #types/webpack-env, which fixed resolve() and resolve.context(). Am I missing another typings package or is this an issue I need to take up on the DT issue tracker?
Requiring non JS or TS resources is currently not supported by the TypeScript server which powers VS Code's JavaScript and TypeScript intellisense. Here's the issue tracking this: https://github.com/Microsoft/TypeScript/issues/15146
As a workaround, try creating a d.ts file in your project with the content:
declare module '*.css' { export default '' as string; }
declare module '*.png' { export default '' as string; }
You can also suppress individual errors by adding // #ts-ignore before the require:
// #ts-ignore
var img = require("../img/image.png");

Categories

Resources