Import module from npm to javascript file - javascript

I am trying to import showdown module in my home.js file.
The GitHub installation guide tells me to run npm install showdown and presents a simple example of using the module, as such:
var converter = new showdown.Converter(),
text = '# hello, markdown!',
html = converter.makeHtml(text);
I have installed the module using that command, but now I m not sure how to use this module inside my home.js situated under app/static/js path. I tried using require but it s not a solution since
it does not exist in the browser/client-side JavaScript.
Project Tree
├── app
│   ├── __init__.py
│   ├── routes.py
│   └── static
│   ├── js
│   │   └── home.js
│   └── styles
│   ├── main.css
│   └── normalize.css
├── config.py
├── package-lock.json
├── package.json
├── run.py
└── node_modules
Javascript file home.js
const textEditor = document.querySelector('.text-editor')
const preview = document.querySelector('.preview')
var converter = new showdown.Converter() // <- error fires here
console.log('text-editor', textEditor)
console.log('preview', preview)
textEditor.addEventListener('keyup', event=>{
const {value} = event.target;
const html = converter.makeHtml(value)
preview.innerHtml = html
});
Question: How do I import this showdown inside my index.js so that I can be able to use every function of the module?

You can use Browserify for this.
It allows you to use require() for requiring node_modules.
Here are the steps in which you can use the showdown npm package in your project.
Install browserify globally using: npm install -g browserify
Use require() to include your npm modules in your project.
const showdown = require('showdown');
Prepare a bundle for accessing require() function in your home.js usnig browserify:
browserify js/home.js > bundle.js
Include the bundle.js file created in your code using the script tag.
<script src="bundle.js"></script>
Here are some resources that explain how to use browserify in more detail:
https://medium.com/jeremy-keeshin/hello-world-for-javascript-with-npm-modules-in-the-browser-6020f82d1072
https://github.com/browserify/browserify#usage
Additionally, this article also explains well how to choose the tool for compiling your front-end applications based on your requirements. And it contains detailed information about how to use browserify

Related

What is the proper way to bundle assets with an NPM module?

I have a library, let's call it my-lib. The packaged code contains some JS and type declarations for that code in /dist, as well as a number of SVG files in /assets:
my-lib
├── assets
│   ├── a.svg
│   ├── b.svg
├── dist
│   ├── index.d.ts
│   ├── index.mjs
│   ├── index.umd.js
├── LICENSE
├── package.json
My intention is to have the JS modules exported on the root of the package, my-lib, with the assets importable from my-lib/assets (when using an appropriate plugin for the user's framework and bundler, E.G. vite-plugin-svgr for React+Vite). This seems to work by default in a create-react-app project with Webpack using import { ReactComponent as A } from "my-lib/assets/a.svg"; and the right declaration file to appease TypeScript, but in a Vite project ends up throwing errors:
[vite] Internal server error: Missing "./assets/a.svg" export in "my-lib" package
The important bits of my package.json:
// package.json
{
"main": "./dist/index.umd.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"./dist",
"./assets"
],
// ...rest
}
Are there specific fields to use for non-JS assets in package.json? Is this simply an issue with bundler config?
Minimum reproducible example

How to structure a simple yarn package for local sharing

I want to create a simple yarn package that can be installed by multiple local yarn projects using yarn add link:/path/to/package. Imagine the package of the package to be shared looks like this
├── package.json
├── tsconfig.json
└── src
├── generated
│   ├── abc.js
│   ├── abc.d.ts
│   └── def.js
│   └── def.d.ts
My goal is that abc and def should be accessible like this
import * from "myPackage/abc"
Currently if I install the above package with yarn add link:/path/to/package then I have to do
import * from "myPackage/src/generated/abc"
I'm a rookie on making typescript packages so forgive me. Can someone point me in the right direction here?
I've tried the suggestion here but it doesn't make a difference.
So it seems I need to set exports and typesVersions in package.json
"exports": {
"./": "./src/generated/"
},
"typesVersions": {
"*": {
"abc": [
"./src/generated/abc.d.ts"
],
"def": [
"./src/generated/def.d.ts"
],
}
},

Unable to import node_module packages in Jupyter notebook extension

I'm trying to import an external javascript module (e.g., log4js). However, I have issues with loading in javascript packages specified in my package.json into my Jupyter extension. My project setup looks something like this:
├── logger/
│ └── __init__.py
│ └── static/
│ └── main.js
├── node_modules/
│ ├── log4js/
│ └── ...
└── pacakge.json
│
└── setup.py
This is what my main.js looks like:
define([
'base/js/namespace',
'jquery',
'log4js'
], function (Jupyter,$,log4js) {
"use strict";
function load_ipython_extension() {
console.log("Loaded Logger")
// var log4js = require("log4js");
var logger = log4js.getLogger();
}
return {
load_ipython_extension: load_ipython_extension
};
});
I am able to import the jquery variable into $ successfully, however, any other package that is installed inside node_module can not be loaded in and results in the same Error: Script error.
Any idea on how to appropriately place the node_module packages into the scope of the Jupyter extension would be very helpful, thanks!
From the informations you gave here I can guess that you need to setup paths to libraries from node_modules. As you can see you have 404 errors in the browser which means that RequireJS is trying to load the modules but from wrong paths. You can read more about paths on official page: https://requirejs.org/docs/api.html#config-paths

Compile files to original location with Babel

I have a folder structure like the following
src
├── a
│   └── test-a.js
└── b
└── test-b.js
I want to use babel to compile the files from ./src. So If I run the following command, I can get it done.
./node_modules/.bin/babel ./src/ -d ./dist/
This will create compiled files (preserving the tree) into ./dist directory. However, I need to compile files and keep in the same directory.
For example, The tree then should look like this
src
├── a
│   └── test-a.js
│   └── test-a.dist.js
└── b
└── test-b.js
└── test-b.dist.js
Is there a way to do that?
I don't know if there's a built-in way to do it with the CLI (I kind of doubt it), but you can script it with the API. Do something like glob in src/**/*.js, loop over the pathnames calling require("babel-core").transform() on each, then do a replace on the pathname like replace(/\.js$/, ".dist.js") and write to the new pathname. There's probably also a way to shell script it to transform to dist/ with the CLI like you're doing now then rename & move those files into src/.

Meteor: Global constant not getting picked up from app/lib/_constants.js

My app directory structure is:
App
├── client
├── lib
│   ├── _constants.js
│   ├── config
│   └── router
├── modules
│   ├── answers
│   └── questions
├── node_modules
│   └── bcrypt
├── public
│   └── imgs
├── server
│   ├── lib
│   ├── roles
│   └── startup
└── settings-example.json
In my _constants.js, I have defined some global variables, e.g. Schemas = {} which I intend to use in the modules > module_name> lib > collections.js or modules > module_name> lib > methods.js
But the global variables are not found in the modules' collections.js. Here's the error I get:
W20160323-21:38:58.977(-7)? (STDERR) ReferenceError: Schemas is not defined
W20160323-21:38:58.977(-7)? (STDERR) at modules/answers/lib/collections.js:22:1
W20160323-21:38:58.977(-7)? (STDERR) at modules/answers/lib/collections.js:89:1
By my understanding, the global variables in the APP/lib/_constants.js file should have been loaded before the deeper modules/module_name/lib/collections.js got loaded, right?
But that's obviously not happening. What am I doing wrong?
Thanks for your help!
Read the "file load order" section from Structuring your application:
There are several load ordering rules. They are applied sequentially to all applicable files in the application, in the priority given below:
HTML template files are always loaded before everything else
Files beginning with main. are loaded last
Files inside any lib/ directory are loaded next
Files with deeper paths are loaded next
Files are then loaded in alphabetical order of the entire path
The way this is implemented, a deeply nested lib is loaded before a less deeply nested lib, which explains your problem. Here are some options:
Don't use lib in your deep paths. E.g. rename the path like modules/questions/stuff/collections.js.
Move your modules into packages.
Upgrade to meteor 1.3 (still pre-release as of this writing) and start using the explicit export/import module syntax.

Categories