I need some help with Gulp. I haven't used Gulp very much, so please forgive me if this is a silly question.
I'm fascinated by the idea of just doing a npm install bootstrap in order to get plug-ins etc. for my projects. But I can't seem to figure out how to I'm supposed to access them after the installation.
I want to use Twitter's Bootstrap framework, but as I haven't had the time to teach myself sass yet, so I just want the normal .css files in my project. When I do an npm install bootstrap it installs in ./node_modules/bootstrap. So what is the best way to import just the .css files to my src/css/ folder while keeping it up to date with npm update (if I'd ever want to update it)?
(Obviously doing <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css"> would be plain wrong?)
I guess I could just add it as a git submodule as an up to date version is available at GitHub - which would accomplish what I'm looking for.
I suppose I'm supposed to do an import 'bootstrap'; or require('bootstrap') but I'm at a loss, so please help me...
If you're just using Gulp on its own, then your best bet would probably be to copy the file to your output directory:
gulp.task("bootstrap", function() {
// This copies the entire folder structure - you could just use one file if you wanted
gulp.src("./node_modules/bootstrap/dist/**/*")
.pipe(gulp.dest("./dist/bootstrap/"));
});
Or concatenate it into your output files using gulp-concat:
var concat = require("gulp-concat");
gulp.task("concat", function() {
return gulp.src([
"./node_modules/bootstrap/dist/css/bootstrap.css",
"./src/my-awesome-styles.css"
])
.pipe(concat("style.css"))
.pipe(gulp.dest('./dist/'));
});
Alternatively, if you're using a module bundler like Webpack, you can import it through your JavaScript (assuming you have the css and style loaders installed and configured, or their equivalent in whatever tool you're using):
import "bootstrap/dist/css/bootstrap.css";
I guess that you just need to call the relative path for the bootstrap file and this should take the latest compiled file whenever you receive update through npm update.
I recommend you to go through this to understand about the file stucture:
https://www.npmjs.com/package/bootstrap
I would never recommend to use import 'bootstrap'; command.
And, adding require('bootstrap') into the Js file which is main entry point for the JS is same as having installing packages locally.
Note: Node packages follows Semantic Versioning guidelines hence you need not to worry. Just an idea use "npm install bootstrap --save" >> this command creates entry into package.json file as "dependencies.
Hope this helps!
Related
I have a Django project with 2 apps. I want to use the Notion API in one of the apps, so I have to install it's NPM module. However, I have never use NPM nor a bundler (I understand I have to use one for the import statement).
I have no idea on how to do it. Where should I install the module? Should I install Webpack or something similar? How can I integrate both of this technologies with Django?
Can someone please explain this to me, or reffer to an article/video explaining?
I have been trying for hours now and I can't find anything detailed.
I have checked the following links:
Django how to use npm modules with static/ templates
https://gist.github.com/brizandrew/685a588fbefbd64cd95ed9ec4db84848
https://www.saaspegasus.com/guides/modern-javascript-for-django-developers/integrating-javascript-pipeline/
https://www.saaspegasus.com/guides/modern-javascript-for-django-developers/integrating-javascript-pipeline/
https://www.techiediaries.com/django-webpack-react/
https://owais.lone.pw/blog/webpack-plus-reactjs-and-django/
https://pythonrepo.com/repo/owais-django-webpack-loader-python-developing-restful-apis
And a lot more.
They either don't have what I need (they are for react), or I can just not understand them. I know there are probably a lot of articles on this, but either I just can't find them, or they are too complicated for me (sorry I'm dumb).
If anyone can help me, it would make my day.
Thanks!
P.S. I am using Typescript, but I can use vanilla JS if necessary.
You have two things to do in order to get your app working the way you want.
Install, configure, and run a module bundler
Use collectstatic
Module bundler:
You have a few choices, but most use webpack because it is the most popular. I prefer rollup but it is all up to preference.
rollup quickstart: https://rollupjs.org/guide/en/#quick-start
webpack: https://webpack.js.org/concepts/
Since you are using Typescript, see the plugins for bundling Typescript
https://webpack.js.org/guides/typescript/
https://github.com/rollup/rollup-plugin-typescript
After you bundle, you should have a main.js file or equivalent. Make sure that main.js is in its own folder. Bundlers will typically do this for you.
Add that directory to your STATICFILES_DIRS in settings.py.
Note that you will need to set a STATIC_ROOT for this to work. This will be a folder that you will store your collected static files at.
Run python manage.py collectstatic
Sidenote: if you are using python manage.py runserver to start your application, you don't need to run collectstatic
For those looking for a -workaround solution- this should be great
I found this website that provides you with the bundles to imported in your static files (.html)
So, for my case I needed to download Chart.js latest version's bundle and I found it available here
https://cdnjs.com/libraries/Chart.js
and add it to your html like so:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js" integrity="sha512-sW/w8s4RWTdFFSduOTGtk4isV1+190E/GghVffMA9XczdJ2MDzSzLEubKAs5h0wzgSJOQTRYyaz73L3d6RtJSg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Like in python i install a package using
pip install django
inside a virtualenv,
Then it puts all the files in site-packages folder. and then i can import the package using
from django.core import mail
But i can easily browse the code of django/core in site-packages
Similarly if I install a package using npm can i see the source of that
Eg:
import React, { useEffect } from "react";
Now i want to see the react file and go through the React and useEffect
Is it possible
I do not have background in Python. So, can't explain or compare in Python way. But, yes! You can read or go through the source code in most of the cases.
Now, talking about the specific example you mentioned in question - React. Things are little complicated as we're talking about one of the popular library. You may wouldn't find React.js or react.js file directly. But, that doesn't mean you can read the source code. Let's do it.
Create an application that has react as dependency (You can create an application using create-react-app).
In this application, you'll have node_modules folder. Within this node_modules, you'll have folder after the name of dependency e.g. react. Go inside this folder.
You'll find the package.json file. Open it and look for main. The main is an entry point of the program/package. It mentioned index.js. So, let's open the index.js file.
If you open the index.js, you'll see that based on environment, they're requiring the react.production.min.js or react.development.js file. Open this react.development.js file from cjs folder.
In this file, do a search for useEffect. You will find a function with the same name.
But, I wouldn't recommended you to read the code in this way, if you're planning for React. You may try this solution. Also, if you're planning to read the source code as starting point, why not start with simple and easy to read packages? And don't forget that if not all then most of the packages are there on GitHub and on NPM website, you'll see the link for the Repository.
I've got quite some experience in (web) development (Java, ASP.NET and PHP amongst all), and fairly new to React and Node JS.
Although I did multiple tutorials and read multiple articles, I feel like I'm missing some point here and there. Currently I'm working on a React app which implements a nice HTML template I found.
One React tutorial I did used Webpack for building and deploying the app (local). This works nice, does the job of transpiling ES6 (.jsx) and SASS using babel. So far so good :)
My template has an image slider (Owl Carousel), so I installed the react-owl-carousel module.
This gave me quite some problems with jQuery (also installed as a module).
After several attempts to fix this I decided to move on to another slider module, React Awesome slider.
I used the module as the README.md explained. But upon building it (npm run build), I got an error that the .scss file within react-awesome-slider could not be transpiled. A message like "are you missing a loader".
So I installed sass, node-sass, sass-loader etc etc and configured these in my webpack.config.js.
I also noticed the react-awesome-slider module within node-modules contained a webpack.config.js.
Long story so far, sorry, now to the essence of this question.
In what way can the modules installed (like react-awesome-slider) be considered "black boxes"?
It doesn't feel logical that all the modules get build when building the main app. The "exclude: /node_modules/," config in webpack.config.js prevents this, not?
So why does the react-awesome-slider give an error about .scss transpiling? I had no .scss rule in my webpack config then.
Will all dependend modules automatically get installed when installing a new module? So when I run "npm i react-awesome-slider --save-dev", will its dependencies also be installed? Or is this not necessary? And do I need to update (webpack) configuration after installing a new module? Or is it really black box and "self-containing"?
Any help would greatly be appreciated!!! Maybe there is a good react-webpack sample app on Github or something like that?
That also confusing me for a really long time. Here are some answers to your question.
people publish packages to the NPM, so a module your project depends on
can be pre-builded or source code, it depends. I have checked react-awesome-slider, it's main field in package.json is dist/index.js, directly import it won't cause an issue because there are no SCSS files.If you follow the CSS module usage instruction you have import react-awesome-slider/src/styles and you will find src/styles.js file import ../styled.scss,so webpack will load it with SCSS loader which you have not configured, that's why an error occurred.
while you install modules, npm will go
through its dependency tree, install its dependencies, dependencies'
dependencies, until there's no more dependency module to install. before npm 3.0 the node_module folder is tree structure reflects the dependency tree, but it causes problems that many modules relay on the same dependency, npm will download and save too many same files, after version 3.0 it becomes flat(release note here, search flat keyword).
You don't need to update your webpack config after you install a dependency cause webpack build process will handle it with file dependency tree. You have installed a package and import it in your activation code, file there will be handle( with its package.json main field file as an entry), you have installed a package without using it or import it in a dead file(dead file means you cannot find it from webpack entry file), it will be ignored by webpack as it's dead code.
I have too many confuse until I read npm docs. Good luck to you.
Node modules are build to execute packages.When the are compiled they have proper configuration to handle extensions that are imported in it and when you import something like .scss in your main app then it does not know about that extension then your webpack need rules to include that extensions.
It does exclude node_modules as the are pre-converted pr pre build.
More over webpack is bit tough so developers create CRA Have look at it.
This must be a commonly solved problem, but I cannot find a whole lot on Google/SO so far.
When we run npm install and fetch say 50+ packages including devDependencies as well as runtime dependencies, npm creates node_modules (if needed) and adds each of those packages inside that folder. This means we end up with thousands of extraneous files included under node_modules. Each of those packages contains their own package.json, README.md, minified files, source files, etc. Our application really only cares about jquery.js (for DEV) and jquery.min.js (for PROD), so it seems to be a waste to include all of these other files into our build and therefore our web server.
Is there a standard when it comes to handle these npm packages in a way so that we simply expose ONLY the necessary files to the user? I imagine many people have this kind of issue but I don't see any built in npm constructs that allow us to do this easily.
See below.. the yellow highlighted files are the only files we really care about in Production, but we get all these extra files as well including the source code.
The most common solution consist of bundling your application on a different machine and then expose the built artefacts on production server.
There are a lot of great JS bundlers out there. The ones I have personally used are Browserify, Webpack, and Rollup. All amazing tools.
The main idea consists of writing your application in a Node environment and then bundle it to make it readable to the browser.
For simpler projects I find Browserify a very good compromise between power and ease of configuration. But it's a matter of taste, at the end. :)
Base on what I read about npm install documentation I do not think there is a option to manipulate the installation in the way you want. The packages will install the way the package author decides to package it, sometimes minified sometimes not.
Having said that, you should look for third party solutions like modclean which does exactly what you want post package installation. Run this command in the root of your project directory
npm install modclean -g
modclean
As long as your test coverage is good, ModClean would be perfect for your need.
Edit the package.json file and remove all the unnecessary dependencies then do
npm install --save
By doing this, it will create a local node_modules folder and only download the necessary packages into it (not the global node_modules folder)
Keep in mind, by default, node checks for local node_modules folder. If it couldn't find it, it will use the global folder.
Also, you don't expose all the packages in the node_modules folder. In fact, they will not be used unless you require(); them in the node.js file
EDIT:
For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes. https://www.npmjs.com/package/jquery
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
So jquery module do things a bit differently behind the scene for node.js comparing to the regular front-end jquery.
It requires jsdom so you will have to download that as well from here https://github.com/tmpvar/jsdom
is there a way I can use an npm package on the client side? For example, I want to use the dateformat(https://www.npmjs.com/package/dateformat) package in my client side javascript file
If you want to use npm on the client you may consider using browserify which is designed for that purpose. The node module system is not compatible with browsers so browserify transpiles the javascript into something that will work. Hence the name : browserify.
I found it wasn't enough to use Browserify. There were still issues with the client-side not finding the variables/functions from the library.
Here are the steps that worked for me:
Install Browserify:
npm install -g browserify
Install a library from npm (I'll use leader-line as an example):
npm i leader-line
You will now have all the npm files needed inside the node_modules directory:
Now we can run the usual Browserify command to bundle the JS file from the npm package:
browserify node_modules/leader-line/leader-line.min.js -o bundle.js
This will produce a bundle.js file outside of node_modules:
This is the file we can bring into the front-end, as we would with a usual JS library.
So, assuming I added my bundle.js file to a libs folder, and renamed bundle.js to leaderline.js, I can simply add the usual line in the header of my index.html file:
<script src="libs/leaderline.js" type="module"></script>
Notice the addition of type="module" to the script tag.
However, this is STILL not enough. The final step is to open the JS file for the library (in my case leaderline.js) and find the main function that needs to be exported (usually somewhere near the top):
var LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"
I need LeaderLine to be available inside my scripts. To make this possible, we simply remove var and add window. in front of the function name, like this:
window.LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"
Now I can use the library client-side without any problems:
HTML:
<div id="start">start</div>
<div id="end">end</div>
JS
new LeaderLine(
document.getElementById('start'),
document.getElementById('end')
);
Some will argue that exposing the function to the window is too "global" for best practices. But the other option is to use module bundlers, which handle the exposing of packages, and this is overkill for many applications, especially if you're trying to whip together a quick front-end to try something out.
I find it odd that so many now publish packages in npm, that are obviously intended for the front-end (e.g. obviously nobody would use leaderline.js in back-end node, yet this is where the package was published, with no available CDN).
Given how tortuous it is to expose front-end functionality from an npm package, one can argue that today's JS ecosystem is a mess.
Most of the packages on NPM are designed for server side and won't work on the client side because of security reasons. You could use NW.js, but the user would have to install your software on there computer.
"NW.js (previously known as node-webkit) lets you call all Node.js modules directly from DOM and enables a new way of writing applications with all Web technologies."
http://nwjs.io/