What's the correct approach for re-building a npm package within my own project? - npm

Presentation:
I built an admin template (css + js) and I uploaded it to npm. The package contains the compiled css/js files in the "dist" folder, and the scss files in the "build" folder. The package has several dependencies which are listed as devDependencies in the package.json:
"devDependencies": {
"datatables.net": "^1.10.19",
"dropzone": "^5.5.1",
"laravel-mix": "^4.0.13",
...
}
There are no dependencies, which I assume is correct because I directly use the compiled css/js (the js is just jQuery code).
There's an admin.scss file which has all the imports:
#import 'abstracts/variables';
#import
'~datatables.net-bs4/css/dataTables.bootstrap4.min.css',
'~easymde/dist/easymde.min.css',
'~flatpickr/dist/flatpickr.min.css',
'~jasny-bootstrap/dist/css/jasny-bootstrap.min.css',
'~selectizebootstrap/dist/css/selectize.bootstrap4.css';
#import
'components/alerts',
'components/cards';
I'm using the admin package in a PHP project (Laravel). The admin package is included in the devDependencies of my PHP project. The admin.css file is included in the php.scss file:
#import '../../node_modules/admin-template/dist/css/admin.css';
The problem:
I need to change some variables of the admin.scss file. So, instead of include the compiled css I need to include the scss:
#import '../../node_modules/admin-template/build/scss/admin';
If I do that, I get errors because the admin template devDependencies are not installed in my node_modules.
If do a npm install within the admin template folder, a node_modules folder is created and all the dependencies are installed inside that folder.
But the errors doens't go away, I think is because of the tilde used in the imports of the scss file: #import '~datatables.net-bs4/css/dataTables.bootstrap4.min.css'. It's looking for the files in the root folder (not within the package).
What should I do?
Add all the admin template devDependencies as devDependencies of my PHP project? Doesn't seems right.
List the admin template devDependencies as dependencies, so when I install the package, all the dependencies get installed too? Doesn't seems right either, those are devDependencies.
Remove the tilde ~ off all the #imports in the admin.scss file? So if I need to include directly the scss I need to do an npm install within the package. And if I already have some of that packages installed in my node_modules, they'll be twice.
Any other options?

Short answer, also put them into "optionalDependencies" field of admin-template/package.json.
This way, when you:
cd php-project
npm install admin-template
# or simply `npm install` if it's already in "dependencies"
"optionalDependencies" of admin-template, like datatables.net-bs4 will be installed into top-level node_modules folder. Plus, "optionalDependencies", the semantic seems pretty damn right to me.
Now if you really care about the install footprint for users who only use .css in your package, then unfortunately, no easy way to do it.
You inevitably require users of .scss to do some extra work. You either provide a guide for them on how to do it manually, or you can provide a script to automate that.
One possible solution is you also provide a bin file.
admin-template/bin/admin-template-enable-sass.js # or .sh if you prefer
// package.json
{
"bin": "bin/admin-template-enable-sass.js"
}
This way, when user npm install admin-template, that bin file is symlinked to top-level node_module/.bin, making it runnable with npx cli command.
Now your .scss advance user can simply type:
npx admin-template-enable-sass
to let your script take care things for them.

Related

How to handle project assets with NPM together with SonataAdminBundle?

Since version 4.x of SonataAdminBundle all assets are handled using NPM and WebPack.
In my project I also have some assets and JS libraries and I'm also using NPM and WebPack.
What should I do in this case? For example, SonataAdminBundle uses libraries such as jQuery, Bootstrap, but I also use them (in my package.json).
One of the ideas that came to my mind is to import the main "app.js" file (vendor/sonata-project/admin-bundle/assets/js/app.js) from SonataAdminBundle which contains all the required components to run to my main "app.js" file and then import my other additional libraries and assets. Next, I would then copy all the dependencies from the SonataAdminBundle package.json file (vendor/sonata-project/admin-bundle/package.json) and paste it into my package.json file.
I am not sure if this approach is correct.
The downside of this solution would be to compare the package.json files after each update of the SonataAdminBundle library and apply any changes.
Do you have other ideas to solve this problem?

How to change src code of Vue in node_modules for testing

I am using Vue 2 (doesn't really matter which version exactly).
I want to test some things that happen behind the hood in Vue. So I decided to add console.log('test123') in Vue's files in node_modules. It turns out that the console log never fires. I put that in all files of Vue in node_modules, even in all files of dist's folder of Vue.
How can I achieve this ? If I fork the repo, then I'd have to upload new versions each time on my repo and then run npm install. I know that will work but wanted to achieve this without forking.
Any ideas what I am missing ?
there are many ways .. but i feel more comfortable using this method :
you can download any npm package in a seperated folder next to your project...
open the folder of the package then run this in the terminal:
npm link
then open the project folder and run
npm link ../package-path # link the dir of your dependency
References
npm-link
How to test an npm package locally

How to let npm use sass which comes from local libsass-dev(installed by apt) instead of downloading its own package?

I have a libsass-dev on my system. But npm will download its own one, which is annoying. How to let npm makes use of libsass-dev?
You can try specifying the absolute path to your module, assuming is outside the node_modules folder.
You can try first the require.resolve('/path/to/my/Module') and if it finds it will return the path to the module, then do the require function.
Or You can create your own folder inside node_modules and require the full folder, something like require('./relativeOrAbsPath/To/My/node_modules/myModule'). The default file is index.js or You can mention in the package.json file using the main property to specify another file name.
Also you can update your modules path using this npm module https://www.npmjs.com/package/app-module-path but this looks first on your node_modules folder. However on prior version 1.x is starting for the bottom of the module.paths list.

How to deploy a package for a private gitlab dependency in Yarn

I am working on a vue project that needs to use another private vue project as a dependency. This other private project is a vue plugin.
I have found how to tell yarn to fetch a package on a private gitlab repository by adding the following line in package.json:
"dependencies": {
"myPackage": "git+https://{token-name}:{token}#gitlab.com/path/to/repo.git#someTag"
}
This works well, and the content of my repo is downloaded in my node_modules. However, here comes my problem :
In this repo, the actual vue plugin is not at the root, it's under a subfolder of the repo, meaning the index.js at the root of the repo is not the one from my plugin (and I guess it is the one yarn will be using).
I have a custom yarn deploy script that compiles my plugin into one JS file and put it in a dist folder, however the dist folder is not versioned. I can use the gitlab CI to generate it, but still i'm pretty sure yarn won't use what is inside the dist folder.
My (broad) question is : how can I use the tools at my disposition (yarn, gitlab-ci) to be able to use my private gitlab repository as a vue-plugin for one of my other project ?
You would tell other packages how to use your packages by using the properties of your package.json. For instance, the main declaration
{
main: 'dist/index.js'
}
This tells node how to resolve your module from your package.
so require('my-vue-plugin') or import MyVuePlugin from 'my-vue-plugin' would resolve to node_modules/my-vue-plugin/dist/index.js, for example.
As far as versioning is concerned -- you don't version the file, or the folder. You version through the version property of your package.json and, in your case, through GIT by using git tag -a v(major).(minor).(patch).
The version that you tag should match the version that you specify in package.json.
I would recommend reading more about semantic versioning and creating a script (like VueJS) to auto-increment your package, version and publish.

Gulp less with images

Is there a way for gulp-less (or some other tool) to take the paths to images that are referenced in the .less/.css file and put the files to the destination folder?
Right now when I install a node module, I #import the css file from /node_modules/... directory to my main .less file and it will be included in the bundle, but the images that come with the module are still located under /node_modules/... folder which I don't plan to deploy so using a relative URL would be pointless.
You should consider using bower to split your dev dependencies (handled by npm, non-deployed stuff) and front-end libs (handled by bower, deployed stuff).
Using a .bowerrc like this, you can tell where to save the libs in you projects structure:
{
"directory": "./<your-public-folder>/libs"
}