Add node module to chrome extension - javascript

I am currently tying to add this single node module to my chrome extension: https://www.npmjs.com/package/get-urls Except I always get the require is not defined error. I have googled this and all I have been able to find are chrome extension templates to use but those give them same require is not defined error as well (and they are confusing to set up). I have built a chrome extension before using the https://www.npmjs.com/package/fuse.js/v/3.4.3 module. I was able to get it to work by adding it into the manifest.json file like this:
"background": {
"scripts": ["node_modules/fuse.js/dist/fuse.js", "background.js"]
}
But I am unable to do this with the get-urls file as the index.js file has require() in it.
'use strict';
const {URL} = require('url');
const urlRegex = require('url-regex');
const normalizeUrl = require('normalize-url');
When I npm installed the get-urls It also installed the folders that all these things are requiring. My question is will I be able to add the node_modules path to each index.js file and remove the require at the top of the files? each index.js file is requiring each other so they are all connected.
Is there an easier way to do this that I am missing?

Related

ASP .Net Core 3.1 octokit rest npm package issues

I use npm and a gulpfile.js to essentially export npm packages to a 'lib' folder under 'wwwroot'; this works a treat and whenever I update a specific npm package if it's in my gulpfile.js watch list it'll push the contents to the 'lib' folder.
The issue I have is that I used to use a manually extracted copy of ocktokit-rest in order to query the public api for some repo data. Recently this has stopped working, I assume that GitHub has updated their api which has had some breaking changes for my old version of ocktokit-rest. So with that in mind I installed #Ocktokit/rest version 18.0.9 using the npm package.json. This then creates the following directory:
~/lib/#octokit/rest/
According to the docs I need to refence one of the index.js files inside this. So because Razor doesn't appreciate the use of the # symbol in the path I use the following in my _layout.cshtml
<script src="#Url.Content("~/lib/#octokit/rest/dist-src/index.js")" type="module"></script>
I added the type="module" as I was initially getting some issues with the import statements inside of the index.js file.
Here's the index.js file contents at the above route:
import { Octokit as Core } from "#octokit/core";
import { requestLog } from "#octokit/plugin-request-log";
import { paginateRest } from "#octokit/plugin-paginate-rest";
import { restEndpointMethods } from "#octokit/plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
userAgent: `octokit-rest.js/${VERSION}`,
});
This then raises the following error in the chrome debugger:
Uncaught TypeError: Failed to resolve module specifier
"#octokit/core". Relative references must start with either "/", "./",
or "../".
I don't particularly like the idea of adjusting the #octokit/ reference in favour of '../../' because then every time my gulpfile.js npm push task runs I'll have to manually change this file. However for the sake of debugging this I went through and adjusted index.js to look like this:
import { Octokit as Core } from "../../core";
import { requestLog } from "../../plugin-request-log";
import { paginateRest } from "../../plugin-paginate-rest";
import { restEndpointMethods } from "../../plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
userAgent: `octokit-rest.js/${VERSION}`,
});
When I did this I got similar error messages for each import that looked something like this:
index.js:4 GET
https://localhost:44364/lib/#octokit/plugin-rest-endpoint-methods
net::ERR_ABORTED 404
Now the above URL is pointed at the directory not a specific file, if I run the above through to a single file I can see it load in the browser and display the file. So If I type:
https://localhost:44364/lib/#octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
I can see the js file displayed in the browser so I know it can be pathed to. Now Ideally I want to be able to use this package in another bit of custom js I wrote that iterates through my repos and creates nice little cards with all the info on, so I'm basically just trying to use it like this:
var octokit = new Octokit({ userAgent: 'agentName' });
But obviously the above is complaining about the existence of Octokit.
So I guess my question is, what the frack? I'm obviously missing something here so if anyone has any ideas in what direction I need to look or research I'd be very grateful.
It's probably nothing to do with the octokit package at all, and much more likely that I just don't understand how to properly import these types of JavaScript libraries into my asp .net core solution
There's a few parts of adding Octokit that you're having difficulties with: handling the # symbol, the scope at which you import it, and the fact that you're trying to use files intended for build tools.
# in a Razor Page
When you're writing JavaScript inline in a <script> tag inside the context of a Razor page, you'll need to escape the # character by using ##. For example, if you were referencing the Octokit path, you would write ##octokit/rest.
Scope
When you're using type=module, your code has module scope, making you unable to reference the Octokit variable outside of the module. In order to break out of module scope, you can attach the Octokit variable to the window object:
window.Octokit = new Octokit({ userAgent: 'agentName' });
Then later on, your code in other script blocks can access Octokit like normal:
const { data } = await Octokit.request("/user");
Building Octokit
The files you're importing are not intended for direct consumption by the browser. It's expecting you to be importing it into JavaScript build tools, not importing it as a module directly from the browser.
The index.js file you're trying to import client side is intended to be used with some JavaScript build tools like Webpack. To get this working the way you want to in gulp, you would need to modify your gulpfile.js to include some kind of a plugin that would import #octocat/rest and output it into a file usable by a browser.
To do this with Webpack, you need to install a Webpack plugin for gulp:
npm install --save-dev webpack-stream gulp-rename
Then, create a file next to your gulpfile.js called index.js that imports the library and does something with it:
import { Octokit } from "#octokit/rest"
window.Octokit = new Octokit({ userAgent: 'agentName' });
Now, modify your gulpfile.js to take index.js and pipe it through the webpack plugin:
const gulp = require('gulp');
const webpack = require('webpack-stream');
const rename = require('gulp-rename');
gulp.task('default', () =>
gulp.src(['index.js'])
.pipe(webpack())
.pipe(rename("index.js"))
.pipe(gulp.dest('lib/octokit/rest/'))
);
After running gulp, you should have an output file that has resolved all of the dependencies necessary for #octokit/rest!
Alternative Solutions
To save the trouble for this specific package, could you instead load Octokit from their CDN? The CDN handles all of the building and package resolution for you. Your code could then be:
<script type="module">
import { Octokit } from "https://cdn.skypack.dev/##octokit/rest";
window.Octokit = new Octokit({ userAgent: 'agentName' });
</script>
(Note that ## will escape the # sign on Razor pages.)
Most packages offer a CDN option for loading their library client side without having to mess around with build tools. Even if they don't officially offer a CDN, sites like jsdelivr or unpkg can still offer a way to import these files.
Sometime in the future, it looks like browsers might support import-maps. Then, you would be able to handle the package resolution through the browser and do something like this on your Razor page:
<script type="importmap">
{
"imports": {
"/##octokit": "/lib/##octokit/"
}
}
</script>
<script type="module">
import { Octokit } from '##octokit/rest';
var octokit = new Octokit({ userAgent: 'agentName' });
</script>
It looks like this might be usable with a polyfill like system-js, where you would add the s.js loader and replace importmap with systemjs-importmap.

Do I have to place any scripts/modules I create and want to import within the node_modules folder?

I am creating a VSCode extension, and following the getting started guide (https://code.visualstudio.com/api/get-started/your-first-extension) have used yeoman scaffold to get started. I created a new file, newModule.js in the same directory and want to import it as a module for use in the main extension.js script. I then do:
const newModule = require('./newModule.js');
This throws an error:
cannot find module 'newModule' require stack: -
This problem disappears if I copy my file to the node_modules folder created by default. I would like to know what is going on here, and what the best way of handling imports is when working with javascript/Node.js/vs-extensions.
I also notice that node_modules folder is not pushed to github by default, why?
The node_modules folder is for storing all the code from the libraries and packages you are using. It is excluded from git because it is a waste of space and a distraction to store them all in your versioning-control, as you can just re-download them anytime.
Just put your module in the same /src directory, and use the import syntax to import it, instead of require.
import newModule from './newModule';
For example, see how it is done in this sample code.
Please instead
const newModule = require('./newModule.js');
Try this
import newModule from './newModule');
// ^^ Do not use file extension
Also make sure that the file you are calling is in the same directory

require.resolve not finding file even though fs can

I'm having a problem with node.js require.resolve the method that makes no sense having with the test I'm running first.
So my Code
let checkPluginCanLoad = (pluginName, pluginFile) => {
return new Promise((res, rej) => {
// build the plugin's class files path
console.log(`looking for file at ${path}/${pluginName}/${pluginFile}`)
let req = `${path}/${pluginName}/${pluginFile}`
// check it exists blocking
let fileState = fs.existsSync(`${req}.js`);
if(fileState){
console.log(`File ${req}.js ${fileState?"exists.":"does not exist."}`);
// it exists try to load it
let plugin = require.resolve(`${req}`);
res(plugin);
}else{
// could not find or load the plugin
rej(`Plugin is invalid can't find or load class for ${pluginFile}`);
}
});
}
The vars are set to , path = "Plugins", pluginName = "TestPlugin", pluginFile = "TestPlugin";
My output is
Plugins from 'Plugins' have been loaded. index.js:36
looking for file at Plugins/TestPlugin/TestPlugin Plugins.js:133
File Plugins/TestPlugin/TestPlugin.js exists. Plugins.js:138 failed to
load plugin 'TestPlugin' with error 'Error: Cannot find module 'Plugins/TestPlugin/TestPlugin''
The final line
load plugin 'TestPlugin' ... comes from the system above this one catching the rejection.
So the file Exists according to FileSystem but the resolver can't find it.
I have tried prepending it with ../ before the path in case it's resolving from the file that is running it and not the application directory,
I have also tried prepending it with ./ in case it's running it from the application directory.
you need to add ./ to tell node that you are targeting local file.
let plugin = require.resolve(`./${req}`);
if you forgot node will search in steps described here
So this is a bug caused by symlinks on windows with junctioned directories,
So for my dev environment it junctions the directories from my Git Repository directory. but Node is running it through the junction directory but seeing the original directory.
E.G
Git repo is in D:\Projects\NodeAppRepo
then the dev environment is running inside D:\Project\NodeApp\
I have index.js, Core/, node_modules/ all running via a junction inside the NodeApp to the paths in the git repo.
so i'm running node index.js inside D:\Project\NodeApp\ wich is in turn loading D:\Project\NodeApp\Core\Core.js this then imports ./Plugins.js this is where the break happens because the path node has for plugins is not D:\Project\NodeApp\Core\Plugins.js it is D:\Projects\NodeAppRepo\Core\Plugin.js

Require in react can't resolve path

I'm trying to use tracking-js library in my project I'm using react but I dont know if I'm doing anything wrong but keep showing that the module is not found, I already check my package.json and the module install. So this is how I require the module:
const tracking = require("tracking");
what am I doing wrong?
For node, including node-based build tools, first make sure that the module is present. Keep in mind that require does not care about the package.json of your app, only about the module files being present.
Check if node_modules/tracking is present.
Make sure the "main" JS file can be found. If there's a node_modules/tracking/package.json file, see if it has a main property and if the file it references exists. If there is no main property, make sure there's an index.js in the root of the module directory.
If all this is fine and you're getting the module not found error at runtime in client-side JavaScript, then your bundling config may be incorrect, and your webpack/browserify/whatever config will have to be scrutinized for bugs.

Requiring/running JavaScript outside of node-webkit application

Suppose I have the following app structure:
outer-folder/
├── my-app/
└── settings.js
where my-app/ is either the unbuilt directory that contains package.json or the packaged application my-app.exe or my-app.app.
I cannot package settings.js with the rest of my app, because I want this file to be editable by users, and loaded upon startup to configure my app. Moreover, I plan to allow settings.js to reside anywhere (for example, in the user's home directory) and be loadable from there.
This works fine when the app is unbuilt. I just have a relative path to the file and require() it like usual. But when the app is built (with grunt-node-webkit-builder if that makes a difference) this fails and I get the dreaded "Cannot find module" error.
I've searched the node-webkit wiki but can't find anything about this issue, am I missing something? What is the best way to load and run an external JavaScript file, like one would do with require(), from a packaged node-webkit app?
I suggest you to use the application data path.
See the documentation here
An exemple
var gui = require('nw.gui');
var path = require('path');
var yaml = require('js-yaml');
var fs = require('fs');
var confPath = path.join(gui.App.dataPath, 'conf', "dev-conf.yml");
try {
conf = yaml.load(fs.readFileSync(confPath, 'utf-8'));
} catch (err) {
throw new Error("Cannot read or parse configuration file '"+confPath+"': "+err);
}
It's a good pratice to separate code and configuration, and App.dataPath aims at the application specific folder in user's application data (different for each OS).
I generally use an installer to copy my configuration file into it.
Next tip: I prefer using YAML instead of JSON for my configuration or settings, because it allows you to insert comments inside the file.

Categories

Resources