Split Typescript logic into several files - javascript

I have several typescript files in my project and one entry file index.ts (output file is created by webpack).
Individual files with logic export nothing.
Eg. file-one.ts:
document.getElementById('btn').onclick = function() {
console.log('Hello world');
}
How can I import files like the one above into main - entry file?
Eg. index.ts:
import `./file-one`
Return ERROR:
ERROR in ./src/index.ts
Module not found: Error: Can't resolve './file-one.ts' in './src/index.ts'

Eg. file-one.ts:
export click() {
console.log('Hello world');
}
How can I import files like the one above into main - entry file?
Eg. index.ts:
import {click} from `./file-one.ts`
document.getElementById('btn').onclick = click;

You should be able to do that without any problem... a module can be imported even if it is not exporting anything.
I noticed that you are using a back-tick here ... it should be a string like import './file-one.ts' ( though a back-tick in that case should raise another error)
Anyway just make sure your webpack configuration can load typescript files, and that the path to your file is correct, and it should work.

Related

Module not found: Error: Can't resolve - Parsed request is a module

I have class components based project (a requirement by company, can't change to function components)
Once I ran elint --fix and started the project again, it gives me this error just for one file.
Parsed request is a module
using description file: C:\Users\Computer\Desktop\shop\package.json (relative paist or is not a directory
C:\Users\Computer\Desktop\shop\src\node_modules doesn't exist or is not a directory
looking for modules in C:\Users\Computer\Desktop\shop\node_modules
The file only contains an exported function that I use elsewhere to dispatch data. I'm not sure why it's looking in node_modules or how to fix this error.
The file looks something like this :
import store, { addToCart } from '../redux/store'
export function addToCartFunc (---props---) {
---code ----
store.dispatch()
}
I have no idea why this was happening, my guess it was recognizing the file as some kind of webpack but I fixed it by importing it as :
import { addToCartFunc } from './addToCartFunc.js'
instead of (like all others):
import { addToCartFunc } from './addToCartFunc'

Jest test runs - Cannot find module error

I have been working on a React Typescript repo and have been running into an annoying issue where in jest is not able to resolve imports relative to root dir.
Cannot find module '~lib/dates' from 'utils.ts'
And this how the import looks like in the component / utils
import { abc } from '~lib/dates'; // this fails to run
If I change this to a relative path jest test runs works as expected
import { abc } from '../../lib/dates'; // this runs as expected
The same path work for some other directories and I am a bit stumped
import { xyz } from '~components/home/constants'; // jest resolves it
import { abc } from '~lib/dates'; // ERR
I tried including moduleNameWrapper in the jestConfig to see if it jest can resolve the imports correctly but it did not help.
package.json
"jest": {
...
"moduleNameWrapper": {
"^~(.*)$": "<rootDir>/src/$1"
}
}
I could for sure update the VS code setting so that auto imports are resolved relatively to the file and not with the root dir but this has been bugging me for a while. It would be great if anyone has any pointers on how best to resolve this.
I am on a monorepo with the following directory structure
repo
server
client
src
components
lib
utils
package.json
Your implementation looks right. But it looks like the option moduleNameWrapper was the wrong option, it's supposed to be moduleNameMapper.
I also have an example as same as you which also uses babel as transplier, it works fine as I added moduleNameMapper. Here is the my example:
Jest configuration:
https://github.com/tmhao2005/lerna-demo/blob/master/packages/share/jest.config.js
Here is the file for testing:
https://github.com/tmhao2005/lerna-demo/blob/master/packages/helper/src/index.ts
https://github.com/tmhao2005/lerna-demo/blob/master/packages/helper/src/index.test.ts
forget the ~ character;
first define root directory to jest (i.e. src/);
then import your stuff from that root directory; (e.g. import { abc } from 'lib/dates')
by the way you can always import your stuff from default root without any configuration like this: import { abc } from 'src/lib/dates'
further read if you are using create-react-app jest absolute import

How to import a module from the static using dynamic import of es6?

I'm trying to add dynamic import into my code to have a better performance on the client-side. So I have a webpack config where is bundling js files. On SFCC the bundled files are in the static folder where the path to that files is something like this: /en/v1569517927607/js/app.js)
I have a function where I'm using dynamic import of es6 to call a module when the user clicks on a button. The problem is that when we call for that module, the browser doesn't find it because the path is wrong.
/en/lazyLoad.js net::ERR_ABORTED 404 (Not Found)
This is normal because the file is on /en/v1569517927607/js/lazyLoad.js.
There is a way to get it from the right path? Here is my code.
window.onload = () => {
const lazyAlertBtn = document.querySelector("#lazyLoad");
lazyAlertBtn.addEventListener("click", () => {
import(/* webpackChunkName: "lazyLoad" */ '../modules/lazyLoad').then(module => {
module.lazyLoad();
});
});
};
I had the same problem and solved it using the Merchant Tools > SEO > Dynamic Mapping module in Business Manager.
There you can use a rule like the following to redirect the request to the static folder:
**/*.bundle.js i s,,,,,/js/{0}.bundle.js
All my chunk files are named with the <module>.bundle pattern.
Here you can find more info :
https://documentation.b2c.commercecloud.salesforce.com/DOC1/topic/com.demandware.dochelp/content/b2c_commerce/topics/search_engine_optimization/b2c_dynamic_mappings.html
Hope this helps.
I believe you'll likely need to do some path.resolve() magic in either your import statement or your webpack.config.js file as is shown in the accepted answer to this question: Set correct path to lazy-load component using Webpack - ES6
We did it in a different way. That required two steps
From within the template file add a script tag that creates a global variable for the static path. Something like
// inside .isml template
<script>
// help webpack know about the path of js scripts -> used for lazy loading
window.__staticPath__ = "${URLUtils.httpsStatic('/')}";
</script>
Then you need to instruct webpack to know where to find chunks by changing __webpack_public_path__ at runtime
// somewhere in your main .js file
// eslint-disable-next-line
__webpack_public_path__ = window.__staticPath__ + 'js/';
Optional step:
You might also want to remove code version from your __staticPath__ using replace (at least we had to do that)
__webpack_public_path__ = window.__staticPath__.replace('{YOUR_CODE_VERSION_GOES_HERE}', '') + 'js/';

Using ember-cli-sheetjs in an ember component

I'm creating a website using ember and am currently having difficulty using the 'ember-cli-sheetjs' module in a component titled 'add-student.js'. I cannot seem to call any functions in the documentation using my current code.
To get the module in ember I added it to my dev dependencies inside package.json and then ran the "npm install" command which successfully installed the "ember-cli-sheetjs" module. I then try and use it by writing:
import Ember from 'ember';
import xlsx from 'npm:ember-cli-sheetjs';
//have also tried directly using the sheetjs module after
//installing sheetjs with the command
//npm install xlsx --save-dev
//import xlsx from 'npm:xlsx';
export default Ember.Component.extend({
fileinput: null, //this is set with an input handler in the hbs
actions: {
fileLoaded: function() {
console.log(this.get('fileinput')); //properly outputs the file name
var workbook = xlsx.readFile(this.get('fileinput'));
},
}
However this results an error saying:
add-student.js:134 Uncaught TypeError: _npmEmberCliSheetjs.default.readFile is not a function
I feel like the problem is that its not following the correct path to the function (which exists in the function documentation). If anyone can tell me what I'm doing wrong it would be a huge help.
Link to the module: https://www.npmjs.com/package/ember-cli-sheetjs
If anyone runs into this problem I have figured out a work around.
First in your index.html include the line:
<script src="assets/parsing/dist/xlsx.full.min.js"></script>
Next create a folder inside public (if it doesn't already exist) called assets. Next create a folder inside assets called 'parsing' and a folder in 'parsing' called 'dist'. Next in 'dist' create a file called 'xlsx.full.min.js'.
Next copy and paste the code from: https://raw.githubusercontent.com/SheetJS/js-xlsx/master/dist/xlsx.full.min.js into the xlsx.full.min.js file.
Finally, in whatever component you want to use the sheetjs module in just put the following below your import statement:
/* global XLSX */
This is a work around but it does allow you to use the sheetjs module.
Use Bower
// bower.json
"dependencies": {
"js-xlsx": "^0.11.5"
}
// ember-cli-build.js
module.exports = function(defaults) {
app.import('bower_components/js-xlsx/dist/xlsx.min.js');
}
and in your component as #Russ suggested:
import Ember from 'ember';
/* global XLSX */

Typescript compiler error when importing json file

So the code is simple:
calls.json
{"SERVER":{
"requests":{
"one":"1"
}
} }
file.ts
import json = require('../static/calls.json');
console.log(json.SERVER);
the generated javascript is correct and when running the node js server, the console log json.SERVER prints '{ requests: { one: '1' } }', as it should.
The typescript compiler (commonjs) however, somehow does not particularly like this situation and throws: "Cannot find module '../static/calls.json'".
Ofcourse I tried writing a .d.ts file, like this:
declare module '../static/calls.json'{
var exp:any;
export = exp;
}
this then obviously throws: "Ambient module declaration cannot specify relative module name".
I also tried different variants, like:
declare module 'calls.json' {
import * as json from '/private/static/calls.json';
export = json;
}
and then requiring:
import json = require('calls.json');
None work properly and have their own little compiler errors :)
I want to use an external .json file because I use commonjs serverside and amd clientside and I want a single file for loading constants.
Use var instead of import.
var json = require('./calls.json');
You're loading a JSON file, not a module, so import shouldn't be used is this case. When var is used, require() is treated like a normal function again.
If you're using a Node.js definition, everything should just work, otherwise require will need to be defined.
TS 2.9 added support for well typed json imports. Just add:
{
"compilerOptions": {
"resolveJsonModule": true
}
}
in your tsconfig.json or jsconfig.json. Now imports such as:
import json = require('../static/calls.json');
and
import * as json from '../static/calls.json';
should be resolved and have proper typings too!
Another solution is to change data.json to data.ts and export like this
export default {
"key" : {
...
}
}
and import as you would expect:
import { default as data } from './data'
This can also be done by using import statement if using webpack v2 which is already packed with json-loader.
Note that this is not async
import data from './data.json';//Note that this is not async
Also, in your typings.d.ts file add the following wildcard module to avoid typescript error saying: Cannot find module
declare module "*.json" {
const value: any;
export default value;
}
For anyone interested in async imports, check this article by 2uality
As of Typescript 2.9 you can import JSON file natively without any additional hack/loader needed.
The following excerpt is copied from said link above.
...TypeScript is now able to import JSON files as input files when using the node strategy for moduleResolution. This means you can use json files as part of their project, and they’ll be well-typed!
./src/settings.json
{
"dry": false,
"debug":
./src/foo.ts
import settings from "./settings.json";
settings.debug === true; // Okay
settings.dry === 2; // Error! Can't compare a `boolean` and `number`
For Angular 6 it can work with simple HTTP get call as below
Service
//interface, could be Array , object
export interface ResultJSON{
}
//Read JSON file for 3DWide
getJSON() {
return this.http.get(this.filepathUrl);
}
Component :import both service and interface and use as below
resultJSON :ResultJSON;
this
.testService
.getJSON()
.subscribe((data: ResultJSON) => {
this.resultJSON= data;
console.log(this.resultJSON);
});

Categories

Resources