Typescript import class - class

I have been trying to get this thing to work for quite a while now, and so far no solution that I have found has worked for me.
This is what I have:
//Test.ts
module t
{
export class Test
{
constructor ()
{
alert("test");
}
}
}
//Main.ts
/// <reference path="Test.ts" />
var test: t.Test = new t.Test();
As you can see I have two files, one is Main.ts and the other one is Test.ts. They are both in the same folder. Also if it helps I am using VS2012 and the Typescript plugin.
Thank you for the help!
EDIT: Oh btw, I get the error (in chrome): Uncaught ReferenceError: t is not defined

You need to include both scripts in your web page:
<script src="test.js"></script>
<script stc="main.js"></script>

Related

Specifying window (global) variable type hinting in VSCode from external JS file without typescript

This may be a silly question but I really don't know where to look.
I'm creating a browser testing environment for a pretty large-scale API written in typescript. This API uses esbuild to build the typescript files into a /dist/ folder with a single index.js entry-point and its appropriate d.ts file.
I've created a /tests/ folder to hold some browser files that includes an index.html file with Mocha and Chai imported. It also imports /dist/index.js which is set globally to a window.myAPI variable.
In /tests/index.html:
import * as myAPI from "./dist/index.js"
Alongside index.html in the tests folder, there are separate JS files included for different tests that run things on window.myAPI... to do assertion tests.
search.test.js
book.test.js
navigate.test.js
I then run a server to host at the root. These separate tests are then imported from /tests/index.html. The separate tests look like this inside:
const { chai, mocha } = window;
const { assert } = chai;
describe("Search", function() {
describe("Setup", function() {
it("Setting URL should work", function() {
const call = myAPI.someCall()
assert.ok(call);
});
});
});
mocha.run();
Everything works, but I have no code hinting for myAPI. I'd like to be able to see what functions are available when I type myAPI, and what parameters they take, and what they should return - along with all my comments on each function.
In typescript you can do things like ambient declarations, but I don't want to make my tests typescript because then I add an unnecessary build step to the tests. But it would be as easy as:
/// <reference path = "/dist/index.d.ts" />
How can I tell VSCode that window.myAPI is an import of /dist/index.js and should import the types as well so I can see them ?
I'm open to different solutions to this, but I feel like this should be pretty simple. I don't know if ESLint is capable of doing something like this, but I tagged it because I feel it's relevant.
Thanks!

Mock JS object in tests on browser platform

I have this simplified dart file using dart:js:
(dataLayer is used for Google tags, if that's any help)
#JS()
import 'package:js/js.dart';
#JS('dataLayer.push')
external void _push(data);
class Manager {
void pushEvent(String event) {
_push(event);
}
}
On the web, it runs correctly and the dataLayer object is being created in a script in the web/index.html file.
I am trying to write a test about it. I would like to verify dataLayer.push is being called with the correct parameters.
I run my test with the command
flutter test --platform chrome
But I get this error:
TypeError: Cannot read properties of undefined (reading 'push')
Is it possible to create a dummy dataLayer variable (and maybe have the hand on it to record the calls to the method .push())? If yes, how?
Here is my attempt:
#TestOn('browser')
import 'package:flutter_test/flutter_test.dart';
import 'package:js/js.dart';
import 'my_project/my_file.dart';
class _DataLayer {
void push(dynamic data) {}
}
#JS('dataLayer')
final dataLayer = _DataLayer();
void main() {
test('It should push the event', () {
Manager().pushEvent('myEvent');
});
}
A way to do it would be to load and use a custom HTML file during the tests where you can include a script to create the js variables you need.
Follow the instructions of the package test.
If your test file name is folder/my_test.dart, then you can create a html file named (folder/my_test.html):
<!doctype html>
<html>
<head>
<title>Custom HTML file title</title>
<link rel="x-dart-test" href="my_test.dart">
<script src="packages/test/dart.js"></script>
<script>
window['dataLayer'] = [];
</script>
</head>
</html>
See this StackOverflow answer and this StackOverflow question.
and then you can run
dart test --platform chrome
However, this is only supported with dart test and not flutter test, see this issue. In it, they recommend writing an integration test instead.

typescript can't resolve non-relative path in import

I have project structure like this
|--src
|--app.component
|--index.ts
|--home.component
|--index.ts
|--tsconfig.json
|--webpack.config.js
And I'm trying to do stuff below in app.component-index.ts
import { HomeComponent } from 'components/home.component'
Typescript couldn't find this module and throws
error TS2307: Cannot find module 'home.component'
Typescript docs say next:
A non-relative import to moduleB such as import { b } from "moduleB",
in a source file /root/src/folder/A.ts, would result in attempting the
following locations for locating "moduleB":
/root/src/folder/moduleB.ts
/root/src/moduleB.ts
/root/moduleB.ts
/moduleB.ts
So for my case I expect it would be like
/src/components/app.component/components/home.component
/src/components/components/home.component
/src/components/home.component
Thanks in advance.
P.S. In my webpack.config I've setted root.resolve to src and everything bundles correct. Typescript-loader prints errors to terminal but everything is bundled and works correctly
So I can guess at the "why" portion of this but I'm relatively new to TypeScript. I have gotten this to work though so I'll try explaining based on that solution as best I can.
What you expect based on the TypeScript Docs would be mostly correct if:
'components/home.component'
were treated as a 'Non-relative import'. I'm fairly certain (based on the solution that worked for me) that TypeScript treats it as an absolute path from the 'compilerOptions.baseUrl' field in your tsconfig.json.
What worked for me was to set it like so:
{
"compilerOptions": {
"baseUrl": ".",
// Other options
}
}
Which essentially tells TypeScript to try and find something like
'components/home.component'
by looking in the same directory as the tsconfig.json file for a directory called 'components' and then to look for a file/directory within it called 'home.component'.
So if your structure looks like:
|--src
|--app.component
|--index.ts
|--home.component
|--index.ts
|--tsconfig.json
|--webpack.config.js
And you set baseUrl to "." you would probably need to format your import like
import { HomeComponent } from 'src/home.component'

(How) can I use System.import in babel along with require.js?

I'm playing a little bit with the new ES6 functionalities and Babel. I'm successfully using the modules export/import functionalities by means of require.js (transpiling into AMD), but the experimental module loader doesn't want to work. Here is my code and configurations:
extract of front-app/tst.js
import {tstimp as functocall} from "front-app/tstimp.js";
...
/**
* LOADING MODULES DYNAMICALLY
*/
System.import('front-app/tst_dyn_mod')
.then(some_module => {
console('using the module!');
some_module.sayHello();
})
.catch(error => {
console.log('error!');
console.log(error);
});
My .babelrc looks like this:
{
"presets": ["es2015", "react"],
"plugins": ["transform-es2015-modules-amd"]
}
and the scripts I import are these ones, in that order:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script data-main="front-app/tst" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.8/require.min.js"></script>
<script src="node_modules/es6-module-loader/dist/es6-module-loader.js"></script>
</head>
<body></body>
</html>
Unfortunately what I get is the following error by using firefox:
error! tst.js:695:9
Error: a is undefined
Error loading http://localhost/es6r1/front-app/tst_dyn_mod
what's that a? Am I missing something? Keep in mind my code is transpiled into AMD, but System is supposed to stay there in the transpiled code (and it IS there). The polyfill should do the dirty job, right?
I successfully get the thing working on Babel 6 with a slighlty different config (babel-node cli & thus commonjs) thanks to this plugin: https://www.npmjs.com/package/babel-plugin-system-import (npm install babel-plugin-system-import-transformer). Here's a excerpt of my .babelrc:
…
"plugins": [
"system-import-transformer",
{
"modules": "common"
}
]
…
Setting amd instead of common like indicated in the documentation should do the trick for you.
Only limitation of this tiny plugin, you should get a plain string module name like System.import("plainString") and not a computed one (nor string concatenation with +, nor new ES6 template literal and neither variable name). It seemds linked to that line of code.
I will try to PR a fix on that limitation if I can.
Just an update on this, https://github.com/thgreasi/babel-plugin-system-import-transformer has support for non string parameters. Just make sure not to use the updated alias package.

Dynamic assets prefix in Ember-CLI build-generated index.html

I asked this question earlier today, and then deleted it, cause I thought I found an answer that was too obvious to post on here. Basically, how do you change something like this in dist/index.html:
<script src="assets/my.js"></script>
to something like this:
<script src="http://my.assets.com/assets/my.js"></script>
I instantly realized that I can just set the src in app/index.html and it will appear in dist/index.html.
But now I'm realizing that there's a better, if slightly more complex, solution - one that allows different settings in different environments. So I am re-adding the question and posting the answer below.
The solution requires ember-cli-inline-content
Brocfile.js:
global require, module, process;
...
if (process.env.EMBER_ENV === 'development') {
app.options.inlineContent = {
assetPrefix: {
content: 'http://my.assets.com/'
}
};
}
index.html:
<script src="{{content-for 'assetPrefix'}}assets/my.js"></script>