Importing npm modules into Google Chrome Extension content script [duplicate] - javascript

I tried so but I have a 'require is not defined' error. I can't find information about that, can someone enlighten the noob in me please?

It's possible, but you have to be careful. Trying to require() a package means that node will try to locate its files in your file system. A chrome extension only has access to the files you declare in the manifest, not your filesystem.
To get around this, use a module bundler like Webpack, which will generate a single javascript file containing all code for all packages included through require(). You will have to generate a separate module for each component of your chrome extension (e.g. one for the background page, one for content scripts, one for the popup) and declare each generated module in your manifest.
To avoid trying to setup your build system to make using require() possible, I suggest starting with a boilerplate project. You can check out my extension to see how I do it.

An updated answer for 2022
Short answer: yes, you can require/import packages. Rather than going through the tedious work of setting up & configuring a bundler like Webpack on your own (especially if you have no experience with them), there are now build tools you can use to create the boilerplate "scaffolding" for a Chrome extension:
Extension CLI -- this one is well-documented and you can also reference the source code of some Chrome extensions that have used this tool (READ: learn how others have set up their code).
Chrome Extension CLI
Benefits of using them:
New projects are initiated with a default project file structure. Super helpful.
They support modern Javascript (ES6, ES2021), so modules work fine.
They already have bundlers integrated and pre-configured (Webpack in both above cases I think). You therefore don't need to install and configure any on your own.
You can use npm as normal to install any packages/dependencies you need.
Then of course, let the official documentation for Chrome Extensions guide you through the rest.

It's not possible to require node modules directly within a chrome extension. However, it is possible to bundle node applications and packages into the browser for use with your extensions. See here for more: Is it possible to develop Google Chrome extensions using node.js?

Yes, It is possible with esm npm packages.
require is commonjs module loader.
Browser doesn't support commonjs modules system
so that this error showed.
Method 1:
Run npm init -y and add "type" :"module" in your package.json.
create path.js file
add this line in path.js
const fullPath = await import.meta.resolve("npm-pkg-name");
const path = fullPath?.match(/(/node_modules.*)/)[0];
console.log(path);
add this line inside package.json
"path": "node --experimental-import-meta-resolve path.js",
Copy console output text. Replace package name with this copied path.
Method 2:
Install other npm package to find and replace
npm packages' virtual path to real path so that chrome browser will find it.
Install Path-fixxer
Add this line in path.js
import setAllPkgPath from "path-fixxer";
setAllPkgPath();
then run command : npm run path.
Now open browser to test it.

Related

Issues running auth0 with (npm) in a Chrome extension (javascript) [duplicate]

I tried so but I have a 'require is not defined' error. I can't find information about that, can someone enlighten the noob in me please?
It's possible, but you have to be careful. Trying to require() a package means that node will try to locate its files in your file system. A chrome extension only has access to the files you declare in the manifest, not your filesystem.
To get around this, use a module bundler like Webpack, which will generate a single javascript file containing all code for all packages included through require(). You will have to generate a separate module for each component of your chrome extension (e.g. one for the background page, one for content scripts, one for the popup) and declare each generated module in your manifest.
To avoid trying to setup your build system to make using require() possible, I suggest starting with a boilerplate project. You can check out my extension to see how I do it.
An updated answer for 2022
Short answer: yes, you can require/import packages. Rather than going through the tedious work of setting up & configuring a bundler like Webpack on your own (especially if you have no experience with them), there are now build tools you can use to create the boilerplate "scaffolding" for a Chrome extension:
Extension CLI -- this one is well-documented and you can also reference the source code of some Chrome extensions that have used this tool (READ: learn how others have set up their code).
Chrome Extension CLI
Benefits of using them:
New projects are initiated with a default project file structure. Super helpful.
They support modern Javascript (ES6, ES2021), so modules work fine.
They already have bundlers integrated and pre-configured (Webpack in both above cases I think). You therefore don't need to install and configure any on your own.
You can use npm as normal to install any packages/dependencies you need.
Then of course, let the official documentation for Chrome Extensions guide you through the rest.
It's not possible to require node modules directly within a chrome extension. However, it is possible to bundle node applications and packages into the browser for use with your extensions. See here for more: Is it possible to develop Google Chrome extensions using node.js?
Yes, It is possible with esm npm packages.
require is commonjs module loader.
Browser doesn't support commonjs modules system
so that this error showed.
Method 1:
Run npm init -y and add "type" :"module" in your package.json.
create path.js file
add this line in path.js
const fullPath = await import.meta.resolve("npm-pkg-name");
const path = fullPath?.match(/(/node_modules.*)/)[0];
console.log(path);
add this line inside package.json
"path": "node --experimental-import-meta-resolve path.js",
Copy console output text. Replace package name with this copied path.
Method 2:
Install other npm package to find and replace
npm packages' virtual path to real path so that chrome browser will find it.
Install Path-fixxer
Add this line in path.js
import setAllPkgPath from "path-fixxer";
setAllPkgPath();
then run command : npm run path.
Now open browser to test it.

Settings up postcss to use VH fix

I'm attempting to use PostCSS to fix the problem where 100vh doesn't account for the browser/navigation bar on mobile devices.
https://github.com/Faisal-Manzer/postcss-viewport-height-correction
The problem is, I have no idea how to set it up and the instructions assume I know how. I have very little experience with JavaScript and don't use any frameworks or know how to, I just do everything in VS Code with no plugins.
I installed the PostCSS extension in VS Code but am unsure what to do next.
The installation says:
"And then add this javascript to public/index.html (for React), or add to template.html (for Preact)."
I don't use React (I don't think?), so what do I do instead?
Then it says:
"Check you project for existed PostCSS config: postcss.config.js in the project root, "postcss" section in package.json or postcss in bundle config.
If you already use PostCSS, add the plugin to plugins list:"
Would postcss.config.js be in my root folder? Am I supposed to create this file?
It then says to do this:
module.exports = {
plugins: [
+ require('postcss-viewport-height-correction'),
require('autoprefixer')
]
}
I added that to my .js file (Or does it go in the css file?), and am getting an error "module is not defined."
Could someone walk me through this as if I had no idea what I'm doing and have only been using JavaScript and VS Code for a week? Because that's where I'm at.
I'm on Windows if that makes a difference.
Part of the instructions say to do:
npm install --save postcss-viewport-height-correction
I don't know where to enter this command. I've come across similar instructions several times, and looking up "How to do npm install" doesn't produce any results. I've largely been avoiding using frameworks and extensions and plugins with JavaScript because I can never figure out how to use them, and every guide I can find assumes I already know what it all means.
Might be a long winded answer, but I'll try to respond to everything.
PostCSS is a JS-based tool for transforming styles with JS plugins. Typically, you use it as a plugin into your front-end build tool such as Webpack, Rollup, etc. You can also use it as a CLI app, manually running your build.
I just do everything in VS Code with no plugins.
Which editor you use is irrelevant. How are you building this content? Is it just plain HTML and CSS files?
I installed the PostCSS extension in VS Code
That extension is just for getting your editor on the same page as your PostCSS config. For example, you might write some CSS with your PostCSS config that will look like totally invalid CSS to your editor, and it would throw errors at this. That extension ensures it follows the same altered rules as your CSS now does, since you're using a tool that changes the rules.
Would postcss.config.js be in my root folder? Am I supposed to create this file?
Yes
I added that to my .js file (Or does it go in the css file?), and am getting an error "module is not defined."
JS, but it's throwing errors because you need to install it
Part of the instructions say to do:
npm install --save postcss-viewport-height-correction
I don't know where to enter this command.
From your terminal. NPM (and Yarn, if you run across it) is a CLI tool for installing Node packages, like PostCSS here.
Here are the instructions for installing Node & NPM: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm

Modules and dynamic importing in Mozilla addon

I found a convenient way of turning my Chrome extension into modules (a lot easier to maintain etc.). I made it like this https://stackoverflow.com/a/53033388/9182284 (turning background.js into a module and then using dynamic import to get modules).
The simplified version of importing:
(async () => {
const src = chrome.extension.getURL("your/content_main.js");
const contentMain = await import(src);
contentMain.main();
})();
My question is: how could I implement it in Mozilla Firefox? As I am developing for both browsers (first for Chrome and then later copy stuff over to Firefox files and change what's needed). Earlier I just went the easy way and included all the functions in the files they are needed for Firefox version but as I have like 20 files at least then it gets dull do edit all of them etc.
When I try to use dynamic import in Firefox addon then it just doesn't load the script at all (no error log or anything in console) so I don't exactly know the problem (does Firefox just not support it at all?).
If you don't mind using a build tool, I found that parcel works pretty well for this. Use the web extension plugin.
Install via NPM
$ npm install parcel parcel-plugin-web-extension --save-dev
Build from the terminal
$ parcel build --out-dir dist-firefox dist/manifest.json

Package an npm module so that it can work in the frontend (eg. with create-react-app) `You may need an appropriate loader to handle this file type`

I have written a node module and published it as a node package. It works when I use it in backend applications (pure nodejs, no babel or transpile).
However, when I use this same npm module in the frontend (in my case a 'create-react-app') application, it breaks. Bellow is the exact error:
Module parse failed: Unexpected token (14:2)
You may need an appropriate loader to handle this file type.
The error is referring to my use of the spread operator (...). I would prefer not to have to rewrite the library, and would rather add some kind of transpiler to package my library. I haven't found a clear solution to this, they are all very convoluted.
I have tried using rollupjs, and https://github.com/insin/nwb. Neither sadly seem to be what I'm after.
Run my code:
You can install the library to your create react app using npm i cbs-proxy-client#0.0.3. And then add the line const cbsProxyClient = require('cbs-proxy-client') or import cbsProxyClient from 'cbs-proxy-client' to any of your scripts.
Advice would be appreciated :)
A library used for frontend is expected to package an already transpiled version of the source javascript. To do this, you might want to use rollup as a build process in your library to create a bundle file. You can use babel to transpile your code for desired browser support. Let's say the bundle file is saved in dist/bundle.js. Now you will modify the package.json to load this bundled file as the entry file using main parameter in package.json
If you are building using rollup or webpack, it is easy to miss that the bundled file should be prepared as a library. This means that importing the file using commonjs should be able to export correct variables. A typical webpack build removes such exports because it is supposed to work straight on a browser. This blog is in my bookmarks titled "js library steps" since I was creating my first js library.
Note that you do not need to put your generated file in version control. You can use npm files property in package.json to package your bundled files while ignoring them in git.

babel-cli vs babel-preset-es2015 vs babel-register vs babel-core?

What are all these babel dependencies? What are each of them for and how do they differ? Which one should I use for my nodejs web app?
I have looked on the API website but is there any guide that puts these into simple human English?
In simple terms:
babel-cli: Is the one you would use if you were trying to
compile an ES6/ES7 module to ES5- and you had a need to do that via a
terminal command.
babel-preset-es2015: Is the package containing
a subset of features that ES6/ES7 provides.
babel-register: A
require that you do and causes every file require there after to run
through babel, thus allowing you to write ES6/ES7 code in every module.
babel-core: Same as "babel-cli" except you would use it programmatically inside your app.
Basically, you could use "babel-register" during development with the "babel-preset-es2015" package set. Then use "babel-cli" or "babel-core" to compile your files before production.
I hope that helps.

Categories

Resources