How do I use NPM in my vanillaJS, html, css project? - javascript

I have a project that has 3 html files namely index.html, about.html and resource.html.
It has two css files, style.css and style1.css. It has two javascript files, script.js and script1.js. Index.html uses style.css and script.js. about.html uses style1.css and script1.js. resource.js also uses style1.css and script1.js. I wanted tried initializing a NPM project, but it asks for an entry point. What do I do?
I want to use webpack to bundle my project, and for that I need to use NPM. This project is fully vanilla.

Your question seems to be specifically related to the entrypoint question asked when you run npm init. The value you specify there will be set to th property main, in package.json.
That property specifies what file/module will be loaded when someone imports or requires you package. As it doesn't look like you are creating an npm package that will be imported and simply wants to use npm to install dependencies, you don't need to care about it. You can use the default value provided: index.js, even if it doesn't exist.
You can read about it here: https://docs.npmjs.com/cli/v9/configuring-npm/package-json#main

As it mentioned in the comments, you should download Node.js first.
Node js come with its package manager called npm.
In my opinion for your project, the webpack bundler could be confusing at first, so I think you should use Parcel instead.
Steps for your project:
step1
After you installed node with npm in your project directory folder run the following script in a terminal:
npm init -y
It will create a package.json file int the root directory of your project.
step2
run the following script in the terminal which will install parcel bundler
npm install --save-dev parcel
step3
in the package.json file you will find a line with"scripts".
add the following lines to it:
"scripts": {
"start": "parcel ./*.html",
"build": "parcel build ./*.html"
},
After you done it, you should just run the following script in your terminal, which will start a dev server on your local machine with automate reload on localhost:1234
npm run start
If you want to bundle your html project, then just run the following script:
npm run build
For better understanding how Parcel works, here is the tools documentation.
Hope it will helps!

The entry point is usually the JavaScript file that is responsible for loading and executing the rest of your code.
In your case, you can use any js script you use or create a main script to which you will attach all the necessary scripts. This will also be helpful when building applications with webpack.
{
"name": "your-project-name",
"version": "1.0.0",
"description": "Your project description",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Your Name",
"license": "MIT"
}
After specifying the entry point in your package.json file, you can then install and configure Webpack to bundle your project.

Related

How to install a npm package from github requiring a build step, e.g. when forking a library?

Assume you use a library like vue3-datepicker. You realize you need to customize something, and as as first step you want to use a custom fork of it.
The issue is, there is a build step when the package is pushed to npm's registry since the project doesn't use plain JavaScript, but may have vue or typescript files.
In this case, that would be npm run build:component, though that depends on the project.
Just installing the fork from github via:
yarn add <GitHub user name>/<GitHub repository name>#<branch/commit/tag>
hence doesn't suffice as then the ./dist folder doesn't exist.
You'll get really strange errors like:
error: [plugin: vite:dep-scan] Failed to resolve entry for package "vue3-datepicker". The package may have incorrect main/module/exports specified in its package.json: Failed to resolve entry for package "vue3-datepicker". The package may have incorrect main/module/exports specified in its package.json.
As a quick and dirty solution, I removed in my fork the ./dist/ folder from the .gitignore, ran the npm i && npm run build:component in my fork, and pushed it.
Huge downside is, the ./dist/ folder is now part of that repository, after each change in my fork I also have to build the files again and push those as well.
I rather have the build process triggered in my application using my fork. Is there a way from my application to say:
When you install that library, you have to run a certain script once you downloaded all the files?
The solution should be usable for both npm and yarn, in the sense that the fork my be installed by either one in different applications.
A quote from npm-install Docs
If the package being installed contains a prepare script, its dependencies and devDependencies will be installed, and the prepare script will be run, before the package is packaged and installed.
so in your fork's package.json you can add
"scripts": {
// ...
"build:component": "rollup -c build/rollup.config.js",
"prepare": "yarn build:component || npm run build:component"
}
If you want to trigger builds after installation, you can use the postinstall or a build script in your package.json. In this script, you can create directories and do other setups, using shell commands or javascript programs:
{
"scripts": {
"build": "mkdir dist && npm run build:component",
"build:component": "some command"
}
}

Can I include bash/sh files as dependencies in package.json?

I have a bash script which I wrote for publishing modules to npm: publish.sh
As I still work on tweaking this script a lot, every time I change it, I need to make the changes in every copy of it in every npm module I am managing.
Is there a way to include this as a dependency in my package.json file so that I just need to run npm update; npm install in order to update it? Maybe the sh file would need to be executed by some wrapper javascript or something like that..?
"scripts": {
"start": "sh ./scripts/publish.sh",
...
}
If you need access to the script in a single project, you can put it in the "scripts" object in package.json.
"scripts": {
"publish": "/bin/sh publish.sh"
}
The above can be run with npm run publish. See npm run-script docs for more information.
If you literally want to add the shell script as a dependency that can be installed (from the public registry or a private registry) with npm install, you can absolutely do that. Lots of not-JavaScript executable things are available in the npm repository. You'll want to create a package.json for the dependency and specify the location of your shell script with the "bin" entry.
An example package you can look at if you get stuck is notes.sh. The source code is on GitHub. Look at the package.json to see how they specified the scripts to run in the "bin" entry. You'll still need to create a "script" entry in your other project to run the installed shell script (or you can run it as an npm hook) though, unless you're running it manually or spawning a child process in your code or something.

how to use webpack on a website project and app

One part of my project (call it an app) is using react which utilizes webpack. Now, I'd like to use webpack on other parts of the site which do not use react. I tried to install webpack in the root folder of the project, but get the errorno -4048, code: 'EPERM' I suspect it has something to do with the fact that webpack is already installed. So, the question is if I can use webpack that is already installed to manage other parts of the site? If yes, I assume that I have to add some key-value pair such as "buildSite": "webpack src/js/site.js dist/bundle.js" Is this the way to go?
Sure you can. running webpack command from npm scripts will search webpack in node_modules.
Assuming you are referring to a Monorepository with server and app project you can have a webpack.config.js for each one of your projects. They can even share common configuration.
Given this folder structure:
root_folder:
-node_modules
-package.json
-src
--server_project
---server.index.js
---webpack.config.js
--app_project
---app.index.js
---webpack.config.js
You can define the correlating npm scripts in package.json:
"scripts": {
"build_server": "webpack ./src/server_project/webpack.config.js",
"build_app": "webpack ./src/app_project/webpack.config.js",
"build": "npm run build_server && npm run build_app"
}
And run:
npm run build

What is a correct approach to a javascript monorepo

I'm trying to figure out correct approach for a javascript monorepo. Imagine monorepo containing packages / libraries:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
Now let's say both lib-a and lib-b packages use webpack as their build tool.
I see two approaches
Add wepback as dependency to root. Include "build" script in both packages: "build": "webpack -p --config webpack.config.js. webpack.config.js could include root webpack.config.js. Then I could use tool like lerna to run the build from root directory (which means webpack binary is recognized. However I will be unable to run the build in specific packages since webpack is not available there. I could probably change the build script to something like "build": "../../node_modules/.bin/webpack -p --config webpack.config.js
Always include webpack in each package. This means that build script will succeed. This also means that each package will have the same dependency and I should probably watch that each package uses same webpack version.
Basically what I'm getting at is how should packages inside monorepo be structured? If any package is published, should it always be possible to build that package separately.
Your approach #2 is right. You handle each package separately as it was an individual, self-contained package.
The advantage of a monorepo lays not in sharing files through the directory structure but in:
Bootstrapping all dependencies to a single node_modules with flat structure, effectively deduplicating them.
Making your packages available to your other packages through regular package import/require() as they were external dependencies. And, thanks to symlinks to node_modules, your "dependency" packages contain always the latest content without publishing.
Enforcing consistent, always up-to-date, dependency structure in all your packages. As you said "This also means that each package will have the same dependency".
Automation tools to perform different maintainance tasks (like build, publish) on all your packages with a single command.
I know it's not so easy at the beginning, but when you dig into Lerna documentation it's becoming more clear. Besides Lerna main page I recommend reading about hoisting, FAQ and individual commands like bootstrap and publish.
Our current configuration is same as you:
root
- node_modules
- packages
+ lib-a
* node_modules
+ lib-b
* node_modules
We use lerna to handle our project: https://github.com/lerna/lerna
You just need to specify your package folder in the lerna.json
{
"lerna": "3.16.4",
"packages": ["packages/*"],
"version": "0.0.0",
"npmClient": "yarn",
"useWorkspaces": true
}
Then in your package.json scripts you can use the line:
"build": "lerna run build",
This will basically run a build in all packages. So as long as your build script in each package has the proper params and webpack installed it will automatically run the webpack build.
After that you can simply handle working in your designated packages.

overriding package.json scripts - NPM

Is there a way to override package.json scripts? I can't change package.json because it will change it for everyone. i.e in our package we have
"script": {
"dev": "yarn dev:build"
}
I would like to add extra memory for this step as it keeps crashing on my computer. i.e
"scripts":{
"dev": "\"node --max-old-space-size=9000 yarn dev:build\""
}
You can't "override" package.json because the filename is hardcoded in NPM. You can create another script entry like:
"scripts":{
"dev": "yarn dev:build"
"devlocal": "\"node --max-old-space-size=9000 yarn dev:build\""
}
Exclude package.json while committing to whatever SCM you are using, and the modified file would remain local to your machine only.
Having said that, what you are asking for (having another file to do the work of package.json), is not possible.
It's not technically overriding a script, but you can execute what would be a script without actually adding it to package.json by calling npm exec in your terminal:
npm exec --max-old-space-size=9000 yarn dev:build

Categories

Resources