NPM dependency that imports/requires from the app's root - javascript

Let's say I create an app called App. It installs an npm dependency called package.
Now let's say package requires that App has the following file structure:
App/
node_modules/
package/
index.js
package.json
folder/
file.js
index.js
package.json
Within App/node_modules/package/index.js, it needs to import/require the file located at App/folder/file.js.
For example:
import File from "../../folder/file";
Is this the best way to do this? Is there any way I can reference the App's root in the import instead of needing to use ../../?

No. This is not the best way to do it. Modules should not require from their users.
Use dependency injection instead - let your user pass you the objects you require:
package/index.js
let File = null;
function init (fileModule) {
File = fileModule;
}
export init;
// ...
This way you can pass the File object from your main app:
App/index.js
import { init } from 'package';
import File from './folder/file';
init(File);
How you design the API to pass your "middleware" is up to you. The above is just a suggestion. You can pass it as an argument to a constructor for example:
const package = new Package(File);
This is in fact how frameworks like Express works. It allows Express to be extended without it knowing the structure of your code:
app.use(someMiddleware); // Express never "requires" your middleware
// instead it allows you to pass middleware to itself

Related

import scoped package from local in nodejs

Currently we have multiple node package published in this format
#company/module1
#company/module2
I would like to be able to load these module from local without installing it so we can modify the code directly.
So I make the link in the folder tree like this
- company/
-- module1 -> ../../module1
-- module2 -> ../../module2
Now I want when I import from the scoped name, it will load from local files instead
import module1 from '#company/module1'
Load from my other folder instead of looking from node_modules instalations.
Can anyone help me on this? Thank you very much.
You can't import the modules, libraries, or a single file in the node.js with the common import statement import Example from "package".
So, try to use the const Example = require('package') instead.
const module1 = require("path/to/the/module1");
const module2 = require("path/to/the/module2");

Properties file in JavaScript / Angular

In Java I usually create application.properties in my resource folder and put configs in there.
And when I need it I just do Properties prop = new Properties(); prop.load(... my file) and then use prop.getProperty("Something")
I want to do something similar in Javascript
In my js code I have this:
// REST API Base URL
var baseUrl = "http://localhost:8083/api";
I want this to be in a application.properties file and then load the value.
How can I achive this?
Thanks
In angular 2+ projects and for a good practices you should create environments folder with one file per env like: environment.js, environment.prod.js.
and into file you can export a constant or by default like that
export const environment = {
apiUrl: '',
googleApiKey: '',
}
and you can import this environment in every file you will needed like
import { environment } from '{relativePath}/environment/environment.js'
If you create different files for every env like prod. You need to replace environment.js for env that you will be build. You have lot of info about this with webpack or other compilers.
I recommend you strongly to develop into a common.js project. It will be more friendly for you importing modules and you will have powerful possibilities of scalable app.
But the easy(Ugly) solution is:
index.html
<head>
<script src="environment.js">
<script src="app.js">
</head>
environment.js
// Declaring environment like that you will have window scoped the variable
// and you will have global access to environment with window.environment
var environment = {apiUrl: 'https://api.url:4100'}
app.js
function example(){
console.log(window.environment.apiUrl); // out https://api.url:4100
}
The approach depends on how you build and/or bundle your AngularJs application. But regardless of that, you'll need to create a config.json file to contain your settings.
If using browserify or webpack, you can import that file via require(...), otherwise you can simply request it via ajax before your app bootstraps.
In any of these cases, the best way to use the configuration data throughout your app is to define it as a constant at the bootstrap phase: app.constant('CONFIG', configData);, assuming that configData is a variable that contains the data from your config.json file.
Then you can use dependency injection to provide CONFIG to all your controllers, services and directives.

How to import file from public folder in react application?

I have a javascript file in the public folder and I want to import that file to components in the folder src/components.
projectFolder
publicFolder
index.html
recorder.js
srcFolder
componentsFolder
Speech.js
Speech.css
But I can't do something like this in my component:
import Recorder from '../../public/recorder'
Because I get the following error:
Module not found: You attempted to import ../../public/recorder which
falls outside of the project src/ directory. Relative imports outside
of src/ are not supported. You can either move it inside src/, or add
a symlink to it from project's node_modules/.
As I've understood it's not allowed to import outside of /src directory, so I was wondering how I could "add a symlink" or if you know other ways to fix it.
I believe you are using create-react-app ... this is a feature included in the ModuleScopePlugin, and you can disable it by ejecting the app and editing your webpack configuration (as described in this answer).
But beware, the feature exists for a reason. The create-react-app build tool only processes the src/ directory, so for example your JavaScript outside of here will not be transpiled by Babel. Furthermore, you're typically trying to avoid polluting the global scope if you're using a bundler like Webpack. So unless you've got a really specific reason why you'd need to do this, I'd say try and move it.
You can modify the react-scripts config with the rescripts library
Create a file called .rescriptsrc.js in your root folder:
module.exports = config => {
const scopePluginIndex = config.resolve.plugins.findIndex(
({ constructor }) => constructor && constructor.name === "ModuleScopePlugin"
);
config.resolve.plugins.splice(scopePluginIndex, 1);
return config;
};
If you're ok not using the actual file in public and having a duplicate js file in the src directory there's a hacky but cool solution if you use vscode. This vscode extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave allows you to trigger a command on save (you can use regex to specify which file saves should trigger which commands) and you can specify a command to run on save as such:
{
"match": "public\\\\recorder.js$",
"cmd": "copy ${file} ${workspaceFolder}\\src\\recorder.js"
}
Now you can import from that duplicated file.
As i can see you want to import parent component in child component.
While defining path './' represents the current directory in which you are working so you can go one level up by following '../' for one level up and the same goes for the upper level directory.
So if you want to import from public folder inside Speech.js component you could do something like this.
// In Speech.js
import Recorder from './../../public/recorder';
Hope this will be useful to you.

How do I require something in root project directory from inside node package library?

I wanna create a node package modules, but I have difficulty to require a file from root project directory to use inside my node package module I created.
If I have directory structure like this
- node_modules
- library_name
- lib
- index.js
- bin
- run.sh
- config.js
If the run.sh called, it will run index.js. Inside index.js, how do I resolve to root directory which later I can require config.js inside index.js?
Package binary can accept configuration path explicitly as an argument.
If package binary doesn't run as NPM script, it shouldn't rely on parent project structure.
If package binary runs via NPM script:
"scripts": {
"foo": "library_name"
}
This will set current working directory to project root, so it could be required as:
const config = require(path.join(process.cwd(), 'config'));
Both approaches can be combined; this is often used to provide configuration files with default locations to third-party CLI (Mocha, etc).
If you're in index.js and config.js is in the directory above node_modules in your diagram, then you can build a path to config.js like this:
const path = require('path');
let configFilename = path.join(__dirname, "../../../", "config.js");
__dirname is the directory that index.js is in.
The first ../ takes you up to the library_name directory.
The second ../ takes you up to the node_modules directory.
The third ../ takes you up to the parent of node_modules (what you call project root) where config.js appears to be.
If you really want your module to be independent of how it is installed or how NPM might change in the future, then you need to somehow pass in the location of the config file in any number of ways:
By making sure the current working directory is set to the project root so you can use process.cwd() to get access to the config file.
By setting an environment variable to the root directory when starting your project.
By passing the root directory in to a module constructor function.
By loading and passing the config object itself in to a module constructor function.
I create module same your module.
And I call const config = require('../config'), it work.

Ember CLI import ES6 file to ember-cli-builds.js

So the ember-cli-builds.js file clearly states
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
I'm importing regular javascript files this way
app.import('vendor/global.js');
but what is the proper way to "specify an object with the list of modules as keys along with the exports of each module as it's value"?
At the "AMD Javascript modules" heading of the guides, it is described like that:
Provide the asset path as the first argument, and the list of modules
and exports as the second.
app.import('bower_components/ic-ajax/dist/named-amd/main.js', {
exports: {
'ic-ajax': [
'default',
'defineFixture',
'lookupFixture',
'raw',
'request'
]
}
});
You can now import them in your app. (e.g. import { raw as icAjaxRaw } from 'ic-ajax';)
Reference From Guide
The selector answer is for older ember, pre ember-auto-import (webpack), and pre Ember Octane.
In modern ember, after npm installing a package, you'll be able to import directly from that package.
Example:
npm install qs
then anywhere in your app
import qs from 'qs';
related, it is recommended to avoid placing files in the vendor folder that you want to integrate with the module system. the vendor exists outside of the bundle, so if you have a standalone module, you can place it in your app folder, maybe under some descriptive folder:
app/external-modules/global.js, allowing you to import from it like:
import * as globalStuff from '<my-app>/external-modules/global';

Categories

Resources