How to use plain js lib in a ts angular 2 app - javascript

I'm building an Angular 2 (rc.4) app with TypeScript and I would like to use D3.
I've installed D3 through npm install, but this is a js module without .d.ts file. However, I've found a .d.ts file here.
What I do now (a component):
import d3 from 'node_modules/d3/build/d3.min.js';
//<reference path="../declaration/d3.d.ts" />
//[...]
export class Test {
constructor() {
this.object = this.d3.select(...);
}
}
If I set a break-point on that line in the TS file, I can execute everything just fine. However, the mapped .js version of this file was converted to:
var d3_min_js_1 = require('node_modules/d3/build/d3.min.js');
[...]
this.object = d3_min_js_1.default.select(...);
The d3_min_js_1 object exists, but there is no 'default', so it throws a undefined exception...
How can I get this mapping right (I'm pretty sure d3.d.ts does nothing) or how can a use the plain javascript in the TS-file (without it getting f*cked up by the compiler)?

I hope this plunker will help you: https://embed.plnkr.co/qM3qrk3swvalQFBh1Db1/

Related

Typescript not compiling enum in symlinked folder

EDIT: Unfortunately this seems like a known issue that cannot be solved without messing with create-react-app, although I could be wrong :( https://github.com/facebook/create-react-app/issues/3547#issuecomment-593764097
I am working on a react project using typescript and firebase functions, with my firebase functions project folder inside the project folder for the react app. As there are lots of enums and interfaces that I want to keep consistent between my frontend (the react app) and my backend (the firebase functions), I use a symlink to share a folder containing files common between these two projects. This works fine with interfaces, but causes errors when I try to use an enum exported from this symlinked folder:
ERROR in ./functions/src/shared-types/roles.ts 3:0
Module parse failed: The keyword 'enum' is reserved (3:0)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| __webpack_require__.$Refresh$.runtime = require('/Users/joel/my-project/node_modules/react-refresh/runtime.js');
|
> enum Roles {
| Admin = 'Admin',
| Access = 'Access',
Repro
Starting from a fresh create-react-app with typescript support, add a folder called shared-types at the same level as src and put a file in it called MyEnum.ts:
// shared-types/MyEnum.ts
enum MyEnum {
Foo = "foo",
Bar = "bar"
}
export default MyEnum;
Then, make a symlink between that folder and another one also called shared-types inside src:
$ ln -s /path/to/project/shared-types /path/to/project/src/shared-types
Then, import and use MyEnum in App.tsx:
// src/App.tsx
import React from 'react';
import './App.css';
import MyEnum from "./shared-types/MyEnum";
function App() {
return (
<div className="App">
<h1>{MyEnum.Bar}</h1>
</div>
);
}
export default App;
Finally, just run npm start:
ERROR in ./shared-types/MyEnum.ts 3:0
Module parse failed: The keyword 'enum' is reserved (3:0)
File was processed with these loaders:
* ./node_modules/#pmmmwh/react-refresh-webpack-plugin/loader/index.js
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| __webpack_require__.$Refresh$.runtime = require('/Users/joel/repro/node_modules/react-refresh/runtime.js');
|
> enum MyEnum {
| Foo = 'foo',
| Bar = 'bar',
Things that aren't causing it
It's not that typescript is ignoring the shared-types folder, as everything compiles fine if you add an interface to that folder and use it in App.tsx. Plus, running tsc --listFilesOnly will return a list including /path/to/project/src/shared-types/MyEnum.tsc.
It's not that my version of typescript doesn't support enums or that enums are disabled, as everything works fine if you add an enum to App.tsx itself.
Thanks in advance for the help! And feel free to suggest better ways of sharing files between these two projects in the comments if there are any!
It turns out that create-react-app doesn't support symlinks under src at all! The fact that the interface stuff worked at all seems to be a fluke.
https://github.com/facebook/create-react-app/issues/3547
This seems to have been a known issue for four years, but there is no blessed solution to it yet. 🫀

What is the standard way to create an Angular Component in the browser?

I am trying to create a simple JS/ESM based Angular example. It has been a while since I have been in the angular space and I see there are really 2 options
Using the UMD lib (I would like to avoid this)
Use the ESM2015 folder and load using ESM (this is what I would like to do)
I try doing this like...
<html>
<head></head>
<body ng-app="jrg-module">
<jrg-element></jrg-element>
<jrg-app></jrg-app>
<script type="module">
import { Component } from "//unpkg.com/#angular/core/esm2015/index.js";
import { platformBrowserDynamic } from "//unpkg.com/#angular/platform-browser-dynamic/esm2015/index.js"
import {ShadowElement, CREATE_ELEMENT} from "//unpkg.com/#jrg/ui/target/jrg-ui.esm.mjs";
class JrgElement extends ShadowElement {
constructor() {
super("<h1>CustomElement</h1>");
this.render();
}
}
CREATE_ELEMENT("jrg-element", JrgElement, {});
const MyComponent = Component({
selector:"jrg-app",
template:"<h1>Angular</h1>"
}).Class({
constructor: function() {}
});
const app = platformBrowserDynamic().bootstrapModule(MyComponent)
</script>
</body>
</html>
But (after taking forever to download 500+ files) I get
Uncaught TypeError: Error resolving module specifier “rxjs”. Relative module specifiers must start with “./”, “../” or “/”.
Can I use the ESM version in the browser or do I have to use UMD? If I can use ESM from the browser is there a link to an example?
I swear Angular used to have a dropdown for their examples where you could switch between TS and JS but I don't see it now.
Have you tried out the website stackblitz it has plenty of angular examples of setting up a new project.
You can also do ng new my-app from the cli to generate a new project locally.
Angular has moved away from javascript in favor of typescript, so you will have to use ESM

How do I call a function in an external js file using typescrpt

We are trying a POC of adding Typescript and Webpack to our Angularjs project.
I am able to get my webpack bundle to generate, however at runtime the program cannot find the various functions in my validator.js. Can you please offer some advice?
login-view.components.ts
declare var findFormNode: any; //function in validator.js
//LogInUser
self.login = function ($event, command) {
if (findFormNode($event.target.id)) {
...
}
}
main.ts is importing the file
import "./../../../CommonStaticFiles/include/js/Validators.js";
bundle.js
eval("/* WEBPACK VAR INJECTION */(function($) {/*\r\n\r\n VALIDATORS\r\n\r\n ... n\n\nfunction findFormNode(
error
ReferenceError: findFormNode is not defined
at LoginController.self.login (login-view.component.ts:28)
at fn (eval at compile (angular.js:NaN), <anonymous>:4:267)
at callback (angular.js:29019)
In order for your functions to be properly imported, there are few things that you have to make sure of.
First, make sure you are exporting your functions correctly. Here's an example of how to export a function from Validator.js:
export const validateFunc1 = ():void => {};
Next, you have to make sure you are using proper import syntax. In order to import the function above, you would do the following:
import {validateFunc1} from "./../../../CommonStaticFiles/include/js/Validators.js";
Alternatively, if you want to import all exported functions at once, then you can use this syntax:
import * as validatorFuncs from "./../../../CommonStaticFiles/include/js/Validators.js";
Lastly, check that the location of Validators.js is correct. It's a common mistake to be looking in the wrong directory. Your code editor can usually help you find the right path to use.

Import array of modules (MDBootstrap js modules) into Laravel Mix

I have a fresh Laravel 5.8 installation and I would like to include the js modules from MDBootstrap.
In my bootstrap.js file I have:
require('./mdb/modules');
The ./mdb/modules.js file has:
exports.modules = [
'./js/_intro-mdb-pro.js',
'./js/scrolling-navbar.js',
'./js/vendor/jquery.easing.js',
'./js/vendor/velocity.js',
'./js/vendor/chart.js',
'./js/vendor/wow.js',
... 30 more
];
The compilation works ok, but of course, it doesn't take any effect from these modules include.
I don't know how to include all of them at once as they are not looking like a regular module so I can import like 'import * from 'my-module'
I also tried the ES6 way:
import * as MDBootstrap from './mdb/modules';
but I got the same result: successful compilation without including them into the compiled js file.
The content of these 'modules' doesn't seem to look like a normal module where we export default {} or some other functions or variables. It looks like:
//mdb/js/scrolling-navbar.js
"use strict";
(function ($) {
var SCROLLING_NAVBAR_OFFSET_TOP = 50;
$(window).on('scroll', function () {
var $navbar = $('.navbar');
if ($navbar.length) {
if ($navbar.offset().top > SCROLLING_NAVBAR_OFFSET_TOP) {
$('.scrolling-navbar').addClass('top-nav-collapse');
} else {
$('.scrolling-navbar').removeClass('top-nav-collapse');
}
}
});
})(jQuery);
Even 'exports.modules = [..]' is not familiar to me. I know about 'module.export = ...' but this 'exports' looks like it's a Node.js object.
I know there's also another method to include the dist version of the plugin. I also tried it, but I got some errors: 'Identifier '_classCallCheck' has already been declared'. I looked deeper and I found that actually many of those files are declaring the '_classCallCheck' function and of course that it a redeclare error. Maybe I can refer to this particular error directly to them (MDBootstrap).
So here I am, trying to include and use these modules/files in my Laravel project without success. Any help is appreciated.

React - webpack exports

Edit - Answer: encapsulating the imports work as required:
# index.js
var myLibrary {
ProfileApp: require('./components/ProfileApp.react'),
ProfileStore: require('./stores/ProfileStore'),
}
module.exports = myLibrary;
I can now do
var lib = require('myLibrary');
var ProfileApp = lib.ProfileApp;
End of edit
I have developped a react/flux libray which I need to package using webpack. I do this for the first time and my exports seem wrong... (the library itself works well).
My (simplified) index.js file is
# index.js
module.exports = require('./components/ProfileApp.react');
module.exports = require('./stores/ProfileStore');
...
The code is correctly compiled and installed in node_modules, but does not work when imported.
# whatever.file.doing.imports
var myLibrary = require('myLibrary'); # works well
var ProfileApp = myLibrary.ProfileApp; # works only if I call it --> myLibrary.ProfileApp()
var ProfileStore = myLibrary.ProfileStore; # does not work and myLibrary.ProfileStore() raises "is not a function error"
I think my exports in index.js should use another syntax. For instance, React Router (https://github.com/rackt/react-router/blob/master/modules/index.js) uses
export Router from './Router';
# which can be simply instantiated writing
var Router = ReactRouter.Router;
This syntax raises an error when used in my library. Do you know if I have to use plugin to be able to use this syntax, or if I can write it differently?
Thank you very much!
The special export syntax that React Router uses is from ES6 and is "transpiled" by the Babel loader that you see in use in the webpack config on line 23. Also note that that line only applies to files that have a ".js" extension. Since you have files with ".react" extensions, you may need to change that line.
Unfortunately that does not explain your issue with having to call ProfileApp as a function. Maybe if you posted the code for the ProfileApp and ProfileStore, that would help.

Categories