How to execute an npm package from the code of another package without first installing it? - node.js

I created a command line package that has dynamically loaded packages in its code.
How can I install a dynamic package inside code?
Example:
hello-so package
export default async function() {
const ex = await import(process.argv[2]);
const raw = await ex.default(process.argv[3]);
}
hello-so-module package
export default async function(hello) {
console.log(hello);
return hello;
}
Run:
npx hello-so "hello-so-module" "Hello stackoverflow"
There will be an error because the hello-so-module package is not installed. But how to install it inside the code, or maybe there are other options?
I think that the user will have to install the dynamic module globally.

Related

Get consuming service's package.name inside an npm package

I have the following
consuming-service
-package.json (has utilities-package as a dependency)
utilities-package (published to npm)
-package.json
-version.js
I'm trying to make version.js return the consuming service's name and version, but I'm not sure how to access consuming-service's package.json from within utilities-package
version.js
const pkg = require('../../package.json') // this doesn't work
function getVersion () {
return {
name: pkg.name,
version: pkg.version,
}
}
I'm struggling with finding the specific terms to google to find my answer.
The two best answers I have found are:
Use process.env.npm_package_name & process.env.npm_package_version. These values are automatically set if the consuming service is run with npm start or yarn start
Pass the package.json into the getVersion function.
// utilities-package/version.js
function getVersion (pkg) {
return {
name: pkg.name,
version: pkg.version,
}
}
// consuming-service
const utils = require('utilities-package')
const pkg = require('../../package.json')
const versionResult = utils.getVersion(pkg)

Self-published NPM package not importing anything when added

I published a very simple NPM package with the following:
module.exports = { foo: "baz" };
When webpacked, it looks like the line below, and this file is referenced as the main property in package.json.
(()=>{var r={579:r=>{r.exports={foo:"baz"}}},o={};!function t(e){if(o[e])return o[e].exports;var p=o[e]={exports:{}};return r[e](p,p.exports,t),p.exports}(579)})();
Now, in a separate project when I install the package and try to import it, I get nothing:
const obj = require('mypackage')
console.log(obj)
// => {}
import obj from 'mypackage'
console.log(obj)
// => {}
What is missing here? How do I get this exported object to come through to the installed NPM package?
Rather than messing with webpack config, my solution was indeed to use Microbundle as suggested by Derek in the comments.
It worked immediately, so the "answer" is that there was something wrong with the webpack config, though I don't know what it was.

Cannot find module './lib/BufferMaker' when use buffermaker in Meteor 1.5.1

I have encountered a problem when use some npm package in Meteor (version 1.5.1), any help on it will be much appreciated.
My Environment:
meteor: 1.5.1
buffermaker: 1.2.0
What I Did:
Create a sample Meteor app.
meteor create test
Install buffermaker
meteor npm install --save buffermaker
Import buffermaker in Meteor app by editing test/client/main.js, add line:
import { BufferMaker } from 'buffermaker';
Full content of test/client/main.js:
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { BufferMaker } from 'buffermaker';
import './main.html';
Template.hello.onCreated(function helloOnCreated() {
// counter starts at 0
this.counter = new ReactiveVar(0);
});
Template.hello.helpers({
counter() {
return Template.instance().counter.get();
},
});
Template.hello.events({
'click button'(event, instance) {
// increment the counter when button is clicked
instance.counter.set(instance.counter.get() + 1);
},
});
Run the Meteor app
meteor npm install
meteor
I got this error in the console of browser (Chrome).
modules-runtime.js?hash=8587d18…:231 Uncaught Error: Cannot find module './lib/BufferMaker'
at makeMissingError (modules-runtime.js?hash=8587d18…:231)
at require (modules-runtime.js?hash=8587d18…:241)
at index.js (modules.js?hash=e9fc8db…:1016)
at fileEvaluate (modules-runtime.js?hash=8587d18…:343)
at require (modules-runtime.js?hash=8587d18…:238)
at main.js (main.js:1)
at fileEvaluate (modules-runtime.js?hash=8587d18…:343)
at require (modules-runtime.js?hash=8587d18…:238)
at app.js?hash=3f48780…:101
Did you try:
import BufferMaker from 'buffermaker';
Some if not most modules do a default export meaning that you don't need the curley braces in your import statement
Turns out buffermaker re-exports it’s main module in a strange way, so first step is to bypass it by importing BufferMaker directly:
import BufferMaker from 'buffermaker/lib/BufferMaker';
Then you’ll find when you call .make(), it will complain about Buffer not existing. To get Buffer on the client, first install meteor-node-stubs
$ meteor npm install --save meteor-node-stubs
Then load the buffer module and stick it on the window so BufferMaker can access it
import { Buffer } from 'buffer';
window.Buffer = Buffer;
/* OR do it with require */
window.Buffer = require('buffer').Buffer;

node require.cache delete does not result in reload of module

I'm writing tests for my npm module.
These tests require to install multiple versions of an npm module in order to check if the module will validate them as compatible or incompatible.
Somehow all uncache libraries or function I found on stackoverflow or the npm database are not working..
I install/uninstall npm modules by using my helper functions:
function _run_cmd(cmd, args) {
return new Promise((res, rej) => {
const child = spawn(cmd, args)
let resp = ''
child.stdout.on('data', function (buffer) {
resp += buffer.toString()
})
child.stdout.on('end', function() {
res(resp)
})
child.stdout.on('error', (err) => rej(err))
})
}
global.helper = {
npm: {
install: function (module) {
return _run_cmd('npm', ['install', module])
},
uninstall: function (module) {
decacheModule(module)
return _run_cmd('npm', ['uninstall', module])
}
}
}
This is my current decache function which should clear all modules caches (I tried others, including npm modules none of them worked)
function decacheModules() {
Object.keys(require.cache).forEach(function(key) {
delete require.cache[key]
})
}
I am installing multiple versions of the less module (https://www.npmjs.com/package/less)
In my first test I am installing a deprecated version which does not have a render-function.
In some other test I am installing an up-to-date version which has the render-function. Somehow if I test for that function that test does fail.
If I skip the first test the other test succeeds. (render-function exists).
This makes me believe that the deletion of require.cache has no impact...
I am using node v4.2.4.
If there is a reference to the old module:
var less = require('less');
Clear module cache will not lead that reference cleared and reload the module.
For that to work, at least you don't store module to variable, use the "require('less')" in place everywhere.

Waiting on 1 test

I have the following test
// tests/CheckboxWithLabel-test.js
jest.dontMock('../test.js');
describe('CheckboxWithLabel', function() {
it('changes the text after click', function() {
var React = require('react/addons');
var CheckboxWithLabel = require('../test.js');
var TestUtils = React.addons.TestUtils;
// Render a checkbox with label in the document
var checkbox = TestUtils.renderIntoDocument(
<CheckboxWithLabel labelOn="On" labelOff="Off" />
);
// Verify that it's Off by default
var label = TestUtils.findRenderedDOMComponentWithTag(
checkbox, 'label');
expect(label.getDOMNode().textContent).toEqual('Off');
// Simulate a click and verify that it is now On
var input = TestUtils.findRenderedDOMComponentWithTag(
checkbox, 'input');
TestUtils.Simulate.change(input);
expect(label.getDOMNode().textContent).toEqual('On');
});
});
when I try to run it though using jest, I get the following error: Waiting on 1 test
I run npm test
What should I do?
You did not specify the version of Node you were using. Your problem could be because you are using a newer version of Node and Jest works with version 0.10.0. This is an open issue on Github (https://github.com/facebook/jest/issues/243)
To downgrade your version of node, use the n package as follows:
npm install -g n # Install n globally
n 0.10 # Installing the correct version of node
This can result in some weird problems with your current packages, so delete your node_modules folder and perform a clean install.

Resources