ES6 imports: can we make this fail? import React, {BadKey} from "react"; - ecmascript-6

I'd like my imports to be more fail-fast. I want my build process to fail if someone tries to import something that does not exist.
For default imports it seems to work fine, as the following will fail:
import Something from "doesNotExist";
But if I import an attribute of an existing module, it does not fail:
import React, {BadKey} from "react";
How can I make it fail by default?
I'm using Webpack / Babel5 / NPM 2.14

Use a strongly-typed language like Typescript, which can error in this condition. We actually moved to eliminate all our default exports and imports, because the name checking available for import { Thing } is super helpful.

If you're already using Webpack, eslint-loader is one way to integrate with ESLint as part of your build process.
Webpack can be a little cryptic with errors during module builds, though, so take note of the NoErrorsPlugin at the bottom of the README.
Also, consider using Webpack's bail flag (set to true) to abandon building as soon as module errors are encountered. IIRC the default Webpack behavior just omits the error-ing module from the emitted bundle with a note in the console, which will result in a runtime error anyway (module missing).

Related

Moment Timezone in Angular 9

Currently, I upgrade my Angular project form 8 to 9.
The project's using a "#types/moment-timezone": "^0.5.30" in package.json
Now this package has been deprecated. https://www.npmjs.com/package/#types/moment-timezone
When I run the project ng serve, it shows up this error message
user.model.ts:3:25 - error TS7016: Could not find a declaration file for module 'moment-timezone'. '/home/bunthai/sftp/upgrade/projectg/ui/ctr/node_modules/moment-timezone/index.js' implicitly has an 'any' type.
Try `npm install #types/moment-timezone` if it exists or add a new declaration (.d.ts) file containing `declare module 'moment-timezone';`
import * as moment from 'moment-timezone';
~~~~~~~~~~~~~~~~~
How to deal with this problem?
I've found the solution: https://stackoverflow.com/a/42505940/10258377
In my case change from import * as moment from 'moment-timezone' to const moment = require('moment-timezone');
You need to remove this import, and import your wanted timezone manualy eg:
import moment from "moment";
import "moment/locale/fr";
moment.locale('fr')
If you don't import another timezone, you'll get the default nodeJS server timezone. If you want another, you need to import it and use it.
Just and advice, stop using this library if you can.

Cant import files, get eslint error: 'import' and 'export' may appear only with 'sourceType: module'

I am using cypress, and I want to import a function from another file.
For some reason I cant seem to be abe to import things.
I get the error on vscode:
Parsing error: 'import' and 'export' may appear only with 'sourceType: module'eslint
And when i run cypress i getthis error from the line:
import test from '../support/helperFunctions'
helperFunctions_1.default is not a function
I think there is no webpack on the project, I searched
Could you please tell me in which direction should i look in order to fix this?
Thanks.
This is not a cypress issue. So import & export of modules are introduced with EcmaScript and by default it doesn't get supported in your JS projects.
So in order to get this work, you have to install babel, which is a transpiler(translate & compiler) and configure accordingly.
Please try to add below two dependencies in your package.json file
"#babel/plugin-transform-modules-commonjs": "7.8.3",
"babel-core": "6.26.3",
Now create .babelrc file and add the below statement which will treat modules to be imported and exported.
{
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
Now run your code and verify.

PhpStorm can't resolve package import even though it exists (react-router-dom)

I am using React (16.12.0) with PhpStorm (2019.3.1).
The package I am importing is react-router-dom (5.1.2)
I will write the following import:
import { NavLink, Switch } from "react-router-dom";
Both packages are imported properly by webpack/babel and the page renders properly when I use both Switch and NavLink.
However purely from the IDE-perspective, I get a warning about Switch: Cannot resolve symbol 'Switch'
It is weird because it is obviously there, and I checked in /node_modules/react-router-dom and Switch.js is there.
Strangely on previous versions of PhpStorm (before several updates and plugin imports and other changes), the Switch import was accurately found by PhpStorm.
I have not updated react-router-dom recently and am using its latest stable build.
Any ideas as to why it might be missing Switch?
EDIT:
I have realized it may be because PhpStorm is having difficulty importing a commonJS module.
I tried changing the Javascript compilation method from React JSX to ECMA 6. That didn't work.
I also tried importing some build libraries for react-router-dom, and that worked for recognizing the Route import strangely but not Switch.
I also tried invalidating the PhpStorm cache and restarting the app, but that didn't work either.
EDIT 2:
Per an answer, I have tried to use option+enter (alt+enter on windows) while my cursor is within react-router-dom to try to install a typescript package, but I don't get the same suggested action as shown on the JetBrains website: https://www.jetbrains.com/help/webstorm/configuring-javascript-libraries.html
All it suggests is switching single quotes to double quotes.
Also I have already installed #types/react-router-dom. Perhaps there is another one that I am missing?
EDIT 3:
The correct answer was to install #types/react-router. For some reason #types/react-router-dom is deceivingly NOT what solves this.
node_modules/react-router-dom/esm/react-router-dom.js exports BrowserRouter, HashRouter, Link and NavLink, but doesn't export Switch, it's not explicitly defined there.
For better completion/type hinting, you can install Typescript stubs for the package: put cursor on "react-router-dom" in import statement, hit Alt+Enter, choose Install TypeScript definitions for better type information::
See https://www.jetbrains.com/help/webstorm/2019.3/configuring-javascript-libraries.html#ws_jsconfigure_libraries_ts_definition_files

is it ok to use the exports keyword with commonjs - webpack 1

Is it ok to use the exports keyword to access the exported values, inside the module it self ? ( is it part of the es6 modules spec ? )
It seems to be working fine with webpack and babel / commonjs modules, the exports keywords contains a reference to all exported methods.
But my concern is that this might not be valid and maybe this is only possible because it's a babel / commonjs enviroment.
Also I am not sure how this would affect tree-shaking, as now it would be impossible to determine which exports are actually being used, since the bindMethods method can access all methods in this module dynamically, without having to declare explicit names.
Example:
import bindMethods from 'module';
var binder = bindMethods(exports);
export function foo(value){
binder(value).bar();
}
export function bar(value){
binder(value).foo();
}
Yes, you'd be right in saying using exports like that isn't valid es6 and is only working because babel transpiles your code into commonjs.
Webpack 1 doesn't support tree shaking so it shouldn't cause any problems there. It would be interesting to see what happens if you disable transform-es2015-modules-commonjs and use Webpack 2 to see whether it does effect tree shaking -- I highly doubt it will though.

Loading multi versioned Web Component dependencies with SystemJS / JSPM?

Just a disclaimer - this is a hypothetical scenario as I'm trying to figure out the best way to handle web component direct and transitive dependencies using something like JSPM and SystemJS.
Scenario 1
Suppose I have 2 web components - component-a and component-b. One is built with momentjs#1.2.4 and another is built with momentjs#1.6.4.
Each component author listed Polymer as a peer dependency and momentjs as a direct dependency in their package.json file like this:
"dependencies": {
"moment.js": ">= 1.0.1 <= 1.8.0"
}
"peerDependencies": {
"Polymer.js": "0.5.0^",
}
So in this case when the developer declares the package.json dependencies on both of these components the package manager could figure out the best version of moment.js to install and make it available. Lets assume that's version 1.8.0.
Great - just one version of moment.js to deal with for both components. Now how do the components load / inject the dependency? Does JSPM and SystemJS currently have the ability to support this?
For example in this article Taming Polymer with SystemJS and Typescript the author performs imports that delegate to SystemJS like this:
import 'elements/app-frontend';
So I suppose momentjs would follow a similar approach and import like this (Within the typescript files of component-a and component-b:
import 'js/momentjs';
In the above case the momentjs dependency does not know what version will be fetched since the import declaration is unaware of the version (since it written at design time).
Later on when the component is used in and component is used in an application JSPM figures out the best for the momentjs depedency to install.
In this case lets assume that it install it in a layout like this:
`jspm_packages/momentjs/momentjs#1.8.0`
So how does JSPM become aware the import statement import 'js/momentjs' translates to the import of jspm_packages/momentjs/momentjs#1.8.0?
In this case it's fairly trivial, but it get more tricky in scenario 2 below ... I think.
Scenario 2
Same as scenario one except the version requirements on momentjs are mutually exclusive. For example component-a requires version 1.2.4 and component-b requires version 2.4.4.
So both components perform the import like this:
import 'js/momentjs';
But jspm_packages installs both versions like this:
`jspm_packages/momentjs/momentjs#1.4.4`
`jspm_packages/momentjs/momentjs#2.4.4`
So now how does SystemJS know to that component-a needs version 1.4.4 and component-b needs version 2.4.4?
To summarize:
1) Is JSPM ok with having multiple versions of the same dependency?
According to this article Introduction to the Jspm package manager and the SystemJs module loader and an answer from guybeford it does, but how then does each component get the right version?
2) Does SystemJS / JSPM have a way of configuring version meta data for each component?
3) Does SystemJS have a way of understanding and injecting the right version of a dependency into the web component?
TIA,
Ole
Also what happens if the component requires several other modules, like CSS etc?
I'm not sure what you mean. You can import multiple modules and other contents (likely via plugins) usting SystemJS.
1) Is JSPM ok with having multiple versions of the same dependency?
I think you partially answered this question. JSPM will always select and install only one version for each component, which best matches the requirements from other components. If there is a conflict, JSPM will ask to choose manually.
So how does JSPM become aware the import statement import 'js/momentjs' translates to the import of jspm_packages/momentjs/momentjs#1.8.0?
The config.js file assigns import names (not sure the nomenclature) for installed packages. It is actually possible to change those names using jspm install x=npm:package syntax. This will result in config like
"x": "npm:package#1.2.3"
You can then both import x and import npm:package#1.2.3.
2) Does SystemJS / JSPM have a way of configuring version meta data for each component?
I think that the structure of config.js has all you need. It contains dependencies with their versions.
"component-a": {
"momentjs": "momentjs#1.2.4"
},
"component-b": {
"momentjs": "momentjs#1.6.4"
}
3) Does SystemJS have a way of understanding and injecting the right version of a dependency into the web component?
I would expect SystemJS to use this information to import the correct version when either component-a or component-b is requested.
I am not sure though how to have JSPM install packages this way, retaining multiple versions of a package. I think it deserves a separate, specialized question.