How to direct Webpack config file to centralized dependencies - javascript

I often want to bundle a Node package for the browser, but I'm very tired of keeping Webpack configs and all the dependencies in every project directory. It creates enormous bloat, when every project needs a fairly small set of loaders: Mainly Babel, CSS/SASS, *SV and HTML|EJS.
So I tried to write a module called 'bundle-module' that can be globally installed and invoked inside a project to produce a version in a local dist subdirectory, which it creates if necessary. I got the module to successfully generate a config file with absolute paths to the inputs and outputs when you pass the desired filenames, like so:
npm install -g wilson428/bundle-module
# cd /path/to/myproj
# assume myproj has an index.js with it's own
# project-specific dependencies in package.json
bundle-module --name=myproj --entry=index.js
I thought this was working, but it turns out that, when using the Webpack API to call the compilation process, it looks for the loaders in the local node_modules, such that I get this error:
EntryModuleNotFoundError: Entry module not found:
Error: Can't resolve 'babel-loader' in '/path/to/myproj'
This is precisely what I don't want--for every project to need it's own copy of babel-loader and every other loader.
So, if I could speak to Webpack in plain language, I would say, "Please, sir or madam, when looking for a loader, please look in the directory from which you were called, not the directory into which you're compiling`.
The bundle-module package has all the correct loaders and other Webpack modules as dependences (also tried devDependencies). I also tried "pre-requiring" babel-loader, which didn't help.
How can I get a globally installed Webpack instance to use it's local dependencies instead of the project's dependencies?

I think I fixed this, but I suspect there's a better solution:
In the generated config file, I had to use absolute paths to the loaders pointing to the installed modules in the bundle-module directory:
loader: path.join(__dirname, '../node_modules/babel-loader/lib/index.js')
(Curiously, even though the package.json in babel-loader points to lib/index.js, naturally, this only seems to work if the complete path is specified.
I'll leave this unanswered just in case anyone has a more obvious, simpler solution!

Related

How to run my local angular project by using globally installed npm packages?

I want to do something like this, where, I want to keep all my packages globally just like node package itself. So for example in my package.json I have a package name called "Highcharts" I want to install it globally I don't want to create a local node_modules folder and use it but I want to access it from outside so next time whenever I want to create a copy of my project folder I should be able to use highcharts directly without using npm install. Is it possible?
globally installed node_modules - > Users/user/AppData/Roaming/node_modules/highcharts
app
src
node_modules (I don't want to keep it)
package.json
tsconfig.json
angular.json
How to link these globally installed node_modules with the current app or any app which we want to create?
Any help will be appreciated. Thank you so much :)
local packages are installed in the project directory
global packages are installed in a single place in your system
Usually it is a good idea to have all npm packages required for your project installed locally (project folder). This makes sure, that you can have dozens of applications which are running a different versions of each package if needed.
export NODE_PATH='yourdir'/node_modules
Hello, if am getting right, you want to keep all dependencies global.
You can just run install with -g command. Those libraries will be available in node installation folder.
From the Node docs
If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then node will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)
Additionally, node will search in the following locations:
1: $HOME/.node_modules
2: $HOME/.node_libraries
3: $PREFIX/lib/node
Where $HOME is the user's home directory, and $PREFIX is node's configured node_prefix.
These are mostly for historic reasons. You are highly encouraged to place your dependencies locally in node_modules folders. They will be loaded faster, and more reliably.
I hope I answered, you just need to manage the paths to node_modules wherever you have kept it.

Linking local library into Angular 5 Project

What i want is to have a library locally that when i change it those changes are reflected in the project that is using the library.
i have check out this library here in my local machine: https://github.com/manfredsteyer/angular-oauth2-oidc
So what i'm doing right now, is that i go to the library directory and then
npm link
And then get in my project directory and do
npm link angular-oauth2-oidc
The library folder appears inside my node_modules folder but i can't manage to use it, since when i start the app ng serve it says:
Cannot find module 'angular-oauth2-oidc'
I'm importing like this:
import { OAuthModule } from 'angular-oauth2-oidc';
I've tried to add the the path under the compilerOptions of the tsconfig.json file but haven't been sucessful.
Any ideas on what i'm missing here? I've tried several suggestions i've found on angular github issues but none solved my problem.
Thanks in advance
npm link in a package folder will create a symlink in the global folder {prefix}/lib/node_modules/ that links to the package where the npm link command was executed
Dont use npm link to add a library to your project, use npm install :
npm install angular-oauth2-oidc --save
You have to install it not just link it, so use this line to with flag --save to ensure that it will be saved in your package.json
npm install [package_name] --save
You can get the package name from the source website or from
https://www.npmjs.com/package/angular2
When you say:
So what i'm doing right now, is that i go to the library directory and
then npm link
Do you mean you are executing npm link in the folder you cloned the repository in? Because if so, that's likely your issue as that's the source directory and not what's actually published as a package. You must build the library, change directory into the distribution folder for the package, and then run npm link. Then when you run builds of that library, any Angular applications with that linked will automatically have the last version of your build in their node_modules.
Also, in your Angular applications where you are using the linked library you'll want to make sure you are setting preserveSymlinks to true in your angular.json.
While you can create multiple projects (e.g. an Angular app and an Angular library) under one Angular project to make this process a bit easier, I prefer to separating these two since I like one git repository to present one module.
First, you need to link your modules to your project's package.json file. Here's how to link files locally in general:
Local dependency in package.json
Linking a plain Typescript library is pretty straight forward as you just create an entry point (usually index.ts) file and export everything you want from there. This file needs to be in the same folder as the package.json file in your project.
An Angular library is a bit different as angular modules needs to be compiled before it can be properly exported. If you just import the module to your project without compiling you will get an error stating this: cannot read property 'ɵmod'. This happens at least at the time of writing this.
So we need to compile the library and then link it:
open two terminal windows
in the first terminal, go to your Angular library's root folder and run ng build --watch
check the output folder of the compiled module, usually something like dist/[library name]
change your Angular project's package.json to point to the output folder e.g. "my-angular-library": "file:../my-angular-library/dist/my-angular-library"
run npm install in the same folder
Add path to your Angular project's tsconfig.json e.g:
compilerOptions: {
"paths": {
"my-angular-library": ["./node_modules/my-angular-library"]
}
}
Otherwise you'll get errors like Error: Symbol MyComponent declared in /path/to/library/my.component.d.ts is not exported from my-angular-library
in the second terminal, go to your Angular project's root folder and run ng serve. Make sure you serve the project only after you have installed the local dependency.
You should now be able to use components, services etc. exported via your library module.
TL;DR
for the library ng build --watch
make the library dependency to point to the output folder e.g. "my-angular-library": "file:../my-angular-library/dist/my-angular-library"
npm i
Add path to your Angular project's tsconfig.json e.g:
compilerOptions: {
"paths": {
"my-angular-library": ["./node_modules/my-angular-library"]
}
}
ng serve

NPM Link to Src Dir Instead of Lib Dir

I'm working on several NPM modules at a time - there is one main module that imports three others. I have used npm link to link the others to the main module, however I am writing all the modules using Babel to transpile the source. When I build one of the modules I run npm run build which runs the transpilation and compiles the files in the modules src directory to its lib directory. However, because each of the modules' package.json file specifies the main file location as lib/index.js this means that for a linked module to appear updated to my main module, I always need to build it.
Is there any way (when using npm link) to have it link to the src dir instead of the lib dir? Failing that, is there a better way to achieve what I want - to see updates to the linked modules code reflected instantly in the main module?
1) An easy way to resolve this is to temporarily change the entry point in your library module's package.json when developing:
/* library-module/package.json */
{
"main": "src/index.js",
...
}
Now wherever you npm link library-module, you should be loading the library module's src/index.js
2) Alternatively, you can setup a watch task to always build to lib after detecting changes in src. This way, your new changes will always be reflected in your consuming module.

Configure bower to install only dist folder

I am trying to learn tools such as bower/grunt/requirejs in order to speed up the development process for my website and to make my code more modularized/efficient. I am currently following this tutorial. How does one make Bower only install the dist folder for my dependencies (setup in my component.json file) instead of the entire Git repository?
What you're looking for is the ignore property in bower.json: https://github.com/bower/bower.json-spec
The developer of the module can use the ignore attribute to exclude files when the module is downloaded and installed through Bower.
If you are the developer of said module, you can use the ignore attribute to exclude everything but the dist folder.
If you're not the developer of the module, then there's not much you can do, you will get whatever the developer of the module has deemed significant. In most cases, this is not a problem.
Here's a typical configuration for the ignore attribute:
{
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"package.json",
"src"
]
}
Bower does not provide any option to do that. Mostly because they have refused to.
All we are left to is hacky ways to deal with it, like grunt-wiredep, which doesn't solve the problem in a strict sense.
Good luck!
From Bower's api documentation, there doesn't seem to be anything to say "Install just the dist folder".
As you are using Grunt already, you could probably create a task to run after your bower install using grunt-contrib-clean to remove unwanted files and folders from the bower_components folder.
Something like this should remove everything from the bower_components folder except dist folders:
clean : {
dist : ['bower_components/*/*', '!bower_components/*/dist']
}
While looking into this I also found grunt-bower-task which seems to do exactly that. The only drawback I see to this method is that you have to create the bower.json by hand first and then run the grunt task.
This doesn't answer your question directly, but may help with what you are trying to accomplish.
There are two plugins: grunt-wiredep and grunt-wiredep-copy which can help you manage your bower dependencies. These automagically add the dependencies to your HTML, and can then grab the required minified ones and copy them to your dist folder.
I am however struggling with some aspects of this at How to manage bower dependencies when developing and deploying with grunt and a dist project folder?

Use local version of node.js package

I'm digging into a node package that uses a CLI, and am trying to extend it by adding some functionality. I've cloned the repo from github, but I've also installed it via npm.
How can I use my local version, instead of the one that's been installed via npm?
Thanks!
When you install a package using npm, it just puts it into the node_modules folder in the folder where you ran it (or if you pass -g, into a global node_modules folder).
require() uses a particular search order to find modules. To get a specific version of a module to load you can take two paths:
Specify a relative path to the module: require("./path/to/myfork/of/module")
Delete the version of the module installed by npm into mode_modules and put your fork of it in there
Make sure that your fork of that module is in a "closer" node_modules folder. Node searches the node_modules in same folder as the file calling require() and then works its way up the folder hierarchy to find a module.
For more information, take a look at http://nodejs.org/docs/v0.4.11/api/modules.html

Categories