error importing functions and variables from other js files - javascript

i am having a server side rendered node-express-js project ..
i have a js file which contains an object , when i am trying to import that file in backend controller files by doing
const _something = require(directory name)
i am able to import it properly
but when i am trying to import the same file in my front-end assets files i am getting an error as following
Uncaught SyntaxError: Cannot use import statement outside a module
on frontend js file i am importing it as :-
require {something} from '../../dir_name'
here is my export
PoStatus = {
"Work Order Raised":"1",
"Pending Request Approval":"2",
"Pending Quotes":"3",
"Quote Pending Approver":"4",
"Pending Purchase Order":"5",
"Purchase Order Raised":"6",
"Purchase Order Closed":"7",
"Work Order Closed":"8",
"Rejected":"9",
"Quote Pending Proc. Mgr.":"10"
}
module.exports={PoStatus}
and my import is :-
import {PoStatus} from '../../../constants/poStatus'
function approveReturnRejectQuote(status) {
$.confirm({
title: 'Confirm!',
content: `Are you sure you want to $
here is a snapshot of my directory
https://i.stack.imgur.com/sIZQy.png
so i am exporting from constants/poStatus to assets/patra/js/quotesDetails
and i am getting a big fat error . however my IDE is giving suggestions regarding what object is imported and what key value pairs it holds but browser throws an error

In nodeJs (js running on Desktop) to import and export you must use:
require('here the path')
module.exports = { /* variables to export */ }
And in Js (js running on browser)
import 'here the path'
export { /*here variables*/}
if you want to use import in nodeJs you must config with webpack: https://webpack.js.org/guides/getting-started/ to use moderJs (with import and export) then it will transform to oldJs
My recomendation:
If you are building something simple use syntax from nodeJs
If you build something more complex you must configure webpack

Related

Import javascript from node_modules in angular

I installed a npm package which contains a javascript file, what I want to use. The js file name is all.js and contains this code:
import { initExtended } from './extended'
import Header from './components/header/header'
function initAll(options) {
// Set the options to an empty object by default if no options are passed.
options = typeof options !== 'undefined' ? options : {}
// Allow the user to initialise GOV.UK Frontend in only certain sections of the page
// Defaults to the entire document if nothing is set.
var scope = typeof options.scope !== 'undefined' ? options.scope : document
// Find first header module to enhance.
var $toggleButton = scope.querySelector('[data-module="govuk-header"]')
new Header($toggleButton).init()
initExtended(options)
}
export {
initAll,
Header
}
File all.js is located in node_modules.
When I tried to import it directly from index.html like:
<script type="module" src="node_modules/#id-sk/frontend/govuk/all.js"></script>
It is not working. Console error, file not found.
I also tried import it via angular.json:
"scripts": [
"./node_modules/#id-sk/frontend/govuk/all.js"
]
Also not working with error "Uncaught SyntaxError: Cannot use import statement outside a module (at scripts.js:15241:1)". The error refers to line:
import { initExtended } from './extended'
I also tried to import it in polyfills but I don't know how to call it.
As you are speaking about angular.json, I assume that you are working in an Angular application bootstrapped using the Angular CLI with default settings.
To be able to use this package #id-sk/frontend in your typescript files, you have to import it directly into your typescript file.
1. Import #id-sk/frontend in your TS files
// Import everything into a local variable
import * as govuk from '#id-sk/frontend';
// Import specific object
import { HeaderExtended } from '#id-sk/frontend';
2. Run ng serve
⚠ Spoil: It will lead to typings errors
3. Let's add or create typings
As #id-sk/frontend is not written in typescript, the compile doesn't know about the typings of this library.
Following this statement, you have two choices:
Find or contribute to DefinitelyTyped in order to create the typings of your package #id-sk/frontend
Create a local file typings.d.ts in your ./src folder to declare an empty module
declare module "#id-sk/frontend"
4. Kill & run ng serve again
Enjoy it!
Go further
You can add typings to your module in order to give you autocompletion on the provided objects of #id-sk/frontend.
``ts
declare module "#id-sk/frontend" {
export interface Options {
scope?: Document
}
export function initAll(options: Options): void;
}

how to correctly use Google Protobuf, when using imports in Javascript

Lets suppose there are two .proto files, file hello.proto and file core.proto.
File core.proto is imported with import statement like
import "core.proto";
content of files:
hello.proto
syntax = "proto3";
import "core.proto";
message GetBalance {
string address = 1;
}
core.proto
syntax = "proto3";
message Block {
string chain = 1;
}
I run protoc with
protoc --proto_path=./ --js_out=import_style=commonjs,binary:./ *.proto
Javascript files are generated, but because of "import" statement there is something like
goog.object.extend(proto, core_pb);
and thats a problem because when I try to import this javascript file into my code,
import * as hello_pb from './hello_pb'
it does not work, it says "proto is not defined" it is a reference error.
What am I doing wrong?
Thanks!
While this answer will not directly solve your import problem, it may give you a workaround.
An alternative to "compiling" protobuf into JS is to use protobufjs which implements protobuf and can handle loading arbitrary .proto files. It has its disadvantages (not as lightweight as your solution could be) but it works well.
Assuming you distribute your .proto in your environment (service, app, whatever it is) importing protobufjs and deserializing a message would be something like:
import { loadSync } from 'protobufjs';
...
const protoRoot = loadSync('path/to/hello.proto'));
const Hello = protoRoot.lookupType('Hello'); // can be some_namespace.Hello
...
let message = Hello.decode(buffer);
Most (if not all) datatypes and encoding/decoding is supported. Check out protobuf project page.

Is there a way to import .html file from JavaScript?

I have the following import statements in my Cloudflare Worker project, to import a html file as a string constant :
import userAgentJsch from './userAgentJsch';
import { parse } from 'cookie';
import test from '.test.html';
It fails with the error:
Module not found: Error: Can't resolve '.test.html' in
I was reading about needing to configure my webpack.config.js file, but I don't have such a file.
Can you please help? I just want to keep my html file separated from the js files, but I can't find a solution I can understand.
View folder structure is used for rendering templates no doubts
to read files in nodejs use this :
const fs = require("fs");
const files = fs.readFileSync("new.html");
and to import
var htmlContent = require('path/to/html/file.html');

Cypress not recognizing my imported module from outside /cypress directory

I am trying to import a module from a file outside my /cypress directory into the /cypress/integration directory's test.spec.js file like so:
import { LAB_MODEL } from '../../models/search/lab-model';
But inside this imported module "LAB_MODEL" there are other files being imported using the "##" at the start of the file imports like
import ExperimentDetails from "##/components/experiment/ExperimentDetails";
and I think this is why Cypress isn't working and giving me this error:
Error: Webpack Compilation Error
./models/search/lab-model.js
Module not found: Error: Can't resolve '##/components/experiment/ExperimentDetails' in '/Users/hidden/models/search'
resolve '##/components/experiment/ExperimentDetails' in '/Users/hidden/models/search'
Parsed request is a module
using description file: /Users/hidden/package.json (relative path: ./models/search)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
So I think this is the reason why my test won't run, but I have no idea how to make Cypress recognize "##" imports and can't find any documentation/stackoverflow answers, any help is appreciated, thanks!
##/ looks like something that gets translated into a full path during the Nuxt build.
(ref The alias Property).
Cypress has a separate build that doesn't know about this Nuxt feature. You could try to replicate it with some webpack config via a preprocessor, but another way is to have your Nuxt app put a reference to lab_model on the window object
// somewhere in the Nuxt app
if (window.Cypress) {
window.lab_model = LAB_MODEL;
}
then at the top of the test
const lab_model = cy.state('window').lab_model;
This has the benefit of giving you the exact same instance of lab_model, in case you wanted to stub something.
In a starter Nuxt app, I added the code window.lab_model = LAB_MODEL in /pages/index.vue, but you can add it in any component that imports it, right after the import statement.
In the spec add a .should() to test the property exists, to allow the app time to settle.
it('gets labModel from the Nuxt app', () => {
cy.visit('http://localhost:3000/')
cy.window()
.should('have.property', 'lab_model') // retries until property appears
.then(labModel => {
console.log(labModel)
// test with labModel here
})
})

How to structure Meteor app and load into Meteor shell

I'm having a number of issues putting together a very simple piece of code as I learn Meteor. See the comments, which are questions.
server/main.js
import { Meteor } from 'meteor/meteor';
import { Post } from './schema'
// Why is this required to make Post available in Meteor.startup?
// Isn't there auto-loading?
Meteor.startup(() => {
console.log(Post)
// This works, but why isn't Post available to meteor shell?
});
server/schema.js
import { Post } from './models/post'
export { Post }
server/models/post.js
import { Class } from 'meteor/jagi:astronomy';
// Why can't this be imported elsewhere, like main.js?
const Posts = new Mongo.Collection('posts');
const Post = Class.create({
name: 'Post',
collection: Posts,
fields: {
title: { type: String },
userId: String,
publishedAt: Date
},
});
export { Post }
In addition to these questions, how can I load my app into meteor shell? Post is undefined there, even though it's defined in Meteor.startup. I tried using .load with an absolute path, but this breaks my app's imports, which use relative paths.
As for which errors I'm confused about:
When I try and use import inside Meteor.startup(), I get an error that the keyword import is undefined. I'm using the ecmascript package.
When I don't import { Class } in the same file where I use Class, I get an unknown keyword error.
If I don't import { Post } in main.js, then Post is undefined.
Not able to load app into Meteor shell.
To access exported objects in Meteor shell, use require:
> require('server/schema.js').Posts.findOne();
To access objects exported by packages, use the package name:
> require('react').PropTypes;
The reason you can't access an object that's imported by another js file is that each file has its own scope here. When Meteor builds your app, it doesn't just concatenate js files like many other build systems do, and that's really a good thing.
Basically a Javascript object gets created for every js file you write. Anything you export in a js file becomes a field in this object which you can access by using require. And import is just a nicer version of the same thing.

Categories