npm package.json aliases like webpack - node.js

i am trying to alias a module however i am not sure how to do that with package.json
in webpack you would do something like this:
module.exports = {
//...
resolve: {
alias: {
'pixi.js': 'pixi.js-legacy'
}
}
};
But what is the equivalent without webpack?

Since NPM Version 6.9 of March 2019 it is supported without installing any additional packages (see the RFC):
npm i aliasName#npm:packageToInstall
⬇⬇⬇
// package.json
"dependencies": {
"aliasName": "npm:packageToInstall#^1.6.1"
}
The idea seems to be that npm: is a URI-like scheme in a dependency version specifier.
Usage:
const alias = require( 'aliasName' );

There is a npm package for this: module-alias.
After installing it you can add your aliases to the package.json, like so:
"_moduleAliases": {
"#root" : ".", // Application's root
"#deep" : "src/some/very/deep/directory/or/file",
"#my_module" : "lib/some-file.js",
"something" : "src/foo", // Or without #. Actually, it could be any string
}
Make sure to add this line at the top of your app's main file:
require('module-alias/register');
You should only use this in final products (and not packages you intend to publish in npm or use elsewhere) - it modifies the behavior of require.

Related

How I can use a commonjs module in my quasar project

I an SSR Quasar project using Vite. Whenever I try to add the #tiptap/extension-code-block-lowlight extension to my project, build it and then node dist/ssr/index.js it throws the following error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/whatever/devotto/devotto.com/node_modules/lowlight/lib/common.js
require() of ES modules is not supported.
require() of /home/whatever/devotto/devotto.com/node_modules/lowlight/lib/common.js from /home/whatever/devotto/devotto.com/dist/ssr/server/server-entry.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename common.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/whatever/devotto/devotto.com/node_modules/lowlight/package.json.
Upon investigation, I have concluded that the issue is the lowlight library being imported by #tiptap/extension-code-block-lowlight.
If I manually go to my node_modules/#tiptap/extension-code-block-lowlight/package.json AND node_modules/lowlight/package.json and remove the line "type": "module", I can run the project with no problem (e.g. yarn build && node dist/ssr/index.js.
This solution works on my current machine but I shouldn't have to touch the node_modules folder.
I would assume that I have to transpile lowlight library which prompts me to try to alter Vite configuration but no luck there as well
module.exports = function() {
return {
build: {
extendViteConf (viteConf, { isClient, isServer }) {
if (isServer) {
viteConf.optimizeDeps = viteConf.optimizeDeps || {};
viteConf.optimizeDeps.include = ['./node_modules/highlight.js'];
viteConf.build.commonjsOptions = viteConf.build.commonjsOptions || {};
viteConf.build.commonjsOptions.include = [/highlight.js/, /node_modules/];
// viteConf.optimizeDeps.entries = [
// 'node_modules/#tiptap/extension-code-block-lowlight/dist/tiptap-extension-code-block-lowlight.cjs',
// 'node_modules/highlight.js'
// ];
}
},
}
}
}
Is there a solution to this issue without having to manually change node_module folder? Thank you very much in advance.
I didn't exactly solve the question. I only applied an automated way to handle this whenever I run the command to build the server using pre scripts.
On my package.json:
{
"scripts": {
"start:test:webserver": "ENV_FILE=test quasar build --mode ssr --port 3000 && node dist/ssr/index.js",
"prestart:test:webserver": "sed -i '/\"type\": \"module\",/d' node_modules/lowlight/package.json && sed -i '/\"type\": \"module\",/d' node_modules/#tiptap/extension-code-block-lowlight/package.json",
}
}

Must use import to load ES Module - lowlight with Quasar app [duplicate]

I an SSR Quasar project using Vite. Whenever I try to add the #tiptap/extension-code-block-lowlight extension to my project, build it and then node dist/ssr/index.js it throws the following error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/whatever/devotto/devotto.com/node_modules/lowlight/lib/common.js
require() of ES modules is not supported.
require() of /home/whatever/devotto/devotto.com/node_modules/lowlight/lib/common.js from /home/whatever/devotto/devotto.com/dist/ssr/server/server-entry.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename common.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/whatever/devotto/devotto.com/node_modules/lowlight/package.json.
Upon investigation, I have concluded that the issue is the lowlight library being imported by #tiptap/extension-code-block-lowlight.
If I manually go to my node_modules/#tiptap/extension-code-block-lowlight/package.json AND node_modules/lowlight/package.json and remove the line "type": "module", I can run the project with no problem (e.g. yarn build && node dist/ssr/index.js.
This solution works on my current machine but I shouldn't have to touch the node_modules folder.
I would assume that I have to transpile lowlight library which prompts me to try to alter Vite configuration but no luck there as well
module.exports = function() {
return {
build: {
extendViteConf (viteConf, { isClient, isServer }) {
if (isServer) {
viteConf.optimizeDeps = viteConf.optimizeDeps || {};
viteConf.optimizeDeps.include = ['./node_modules/highlight.js'];
viteConf.build.commonjsOptions = viteConf.build.commonjsOptions || {};
viteConf.build.commonjsOptions.include = [/highlight.js/, /node_modules/];
// viteConf.optimizeDeps.entries = [
// 'node_modules/#tiptap/extension-code-block-lowlight/dist/tiptap-extension-code-block-lowlight.cjs',
// 'node_modules/highlight.js'
// ];
}
},
}
}
}
Is there a solution to this issue without having to manually change node_module folder? Thank you very much in advance.
I didn't exactly solve the question. I only applied an automated way to handle this whenever I run the command to build the server using pre scripts.
On my package.json:
{
"scripts": {
"start:test:webserver": "ENV_FILE=test quasar build --mode ssr --port 3000 && node dist/ssr/index.js",
"prestart:test:webserver": "sed -i '/\"type\": \"module\",/d' node_modules/lowlight/package.json && sed -i '/\"type\": \"module\",/d' node_modules/#tiptap/extension-code-block-lowlight/package.json",
}
}

setup webpack config in nextJS (next.config.js)

I'm working with NextJS and using react-data-export plugin to generate xls files.
in the description it says :
This library uses file-saver and xlsx and using
json-loader will do the magic for you.
///webpack.config.js
vendor: [
.....
'xlsx',
'file-saver'
],
.....
node: {fs: 'empty'},
externals: [
{'./cptable': 'var cptable'},
{'./jszip': 'jszip'}
]
but I have no idea how to implement it and got error like this :
The static directory has been deprecated in favor of the public directory. https://err.sh/vercel/next.js/static-dir-deprecated
Defining routes from exportPathMap
event - compiled successfully
> Ready on http://localhost:80 or http://localhost
> Ready on https://localhost:443 or https://localhost
event - build page: /menu_accounting/ReportGross
wait - compiling...
error - ./node_modules/react-export-excel/node_modules/xlsx/xlsx.js
Module not found: Can't resolve 'fs' in '/home/ahmadb/repos/lorry-erp/node_modules/react-export-excel/node_modules/xlsx'
Could not find files for /menu_accounting/ReportGross in .next/build-manifest.json
I had the same problem, the solution for me was this:
Install this packages (if you installed, ignored this)
npm install file-saver --save
npm install xlsx
npm install --save-dev json-loader
Add this to your nextjs.config.js
const path = require('path')
module.exports = {
...
//Add this lines
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: 'empty'
}
}
return config
}
}

Access config values in package.json

I have recently introduced https://www.npmjs.com/package/config to handle my config:
...
config/
dev.json
uat.json
production.json
package.json
In dev.json I have something like:
{
"someVar": "something"
}
I used to be able to access config values in package.json like:
"scripts": {
"some_command": "do_something $npm_package_config_someVar"
}
But now this doesn't work - those variables are empty.
How can I access values from config/dev.json in packages.json?
Edit: using $npm_config_someVar is also empty
var pkg = require('./package.json');
console.log(pkg.name);

Grunt and NPM, package all production dependencies

I am unsure when the way the NPM installs dependencies changed.
In the past I remember that if in my project.json I had a dependency on "abc", which in turn would depend on "xyz", a npm install would result in something like:
package.json
node_modules/
abc/
node_modules/
xyz/
some-dev-dep/
When packaging my node project to be used by AWS Lambda, I would have to include that node_modules structure (less any dev-dependencies that were there). I would use Grunt for my packaging, so I wrote this handy thing to help me get all production dependencies into this zip (extracting part of my gruntfile.js):
function getDependencies(pkg) {
return Object.keys(pkg.dependencies)
.map(function(val) { return val + '/**'; });
}
var config = {
compress: {
prod: {
options: {
archive: 'public/lambda.zip'
},
files: [
{ src: 'index.js', dest: '/' },
{ expand: true, cwd: 'node_modules/', src: getDependencies(pkg), dest: '/node_modules' }
]
}
}
};
This would work because dependencies of my dependencies were nested.
Recently (or maybe not-so-recently) this has changed (I am unsure when as I was using very old version of NPM and updated it recently).
Now if I depend on "abc" which in turn depends on "xyz" I will get:
node_modules/
abc/
xyz/
some-dev-dep/
As you can see, my way of getting only production dependencies just won't work.
Is there any easy way to get only list of production dependencies (together with sub-dependencies) within grunt job?
I could do it using recursive function scanning for my dependencies, and then checking project.json files of those and then searching for sub-dependencies etc. This approach seems like a lot of hassle that is possibly a common scenario for many projects...
Here is a function that returns an array of the production dependency module names. (Note: you might need to have the 'npm' module installed locally in your project for this to work.)
/**
* Returns an array of the node dependencies needed for production.
* See https://docs.npmjs.com/cli/ls for info on the 'npm ls' command.
*/
var getProdDependencies = function(callback) {
require('child_process').exec('npm ls --prod=true --parseable=true', undefined,
function(err, stdout, stderr) {
var array = stdout.split('\n');
var nodeModuleNames = [];
array.forEach(function(line) {
var index = line.indexOf('node_modules');
if (index > -1) {
nodeModuleNames.push(line.substr(index + 13));
}
});
callback(nodeModuleNames);
});
};
This change was introduced with the release of npm 3 (see npm v3 Dependency Resolution).
It's not exactly clear why you need to use Grunt at all. If what you want to do is get only production dependencies you can simply run:
npm install --production
With the --production flag, all dev dependencies will be ignored. The same is also true if the NODE_ENV environment variable is set to 'production'.

Resources