in parceljs how to make it pick the min file in node modules - node-modules

I am using 'animate.css' as a npm package. to use it I specify import 'animate.css' during development. But in production it says to include 'animate.min.css'. How to specify to parceljs to pick the animate.min.css during production build.
or would import animate.css would be able to resolve to right animate.css in development build and animate.min.css in production build. how does the resolver know to pick right file as the main file is specified as animate.css in the package.json
But the there is "Files" property in package.json ...not sure if it can help.

The high-level answer is that parcel automatically minifies and optimizes css files, so you don't need to do anything special to make sure that your production build is as small as possible.
If you want to understand in detail how parcel handles this particular package, read on.
Parcel generally follows node resolution conventions to figure out which files to actually import when you reference a package name.
In this case, the import "animate.css" will tell parcel to go looking in the nearest node_modules folder for a for a subfolder called animate.css. It finds it, and then looks for the package.json file at the root. In this case, the package.json has a main field that points to a file called animate.css (e.g. the un-minified version).
Parcel will use that file as the basis for development and production builds. When you run parcel in development, it leaves this file untouched. When you run parcel build it will process this (unminified) file through cssnano so the build output is minified.
So the interesting fact is that even though there is another file called node_modules/animate/animate.min.css living there, Parcel is able to achieve the desired behavior without touching it. The publishers of animate.css included it for other folks that aren't using a bundler that's as awesome as parcel - you can safely ignore it.

Related

What does yarn --pnp?

There is this new shining Yarn feature called Plug'n'Play.
I would like to know what it does exactly?
I know it's creating a .pnp folder and a .pnp.js file, but does it change anything else on the machine, like a config file somewhere?
Thank you.
I designed and implemented PnP, so I can talk hours about it 🙂
tl;dr: We only write the .pnp.js and .pnp folders (on top of the regular Yarn cache). We don't store configuration anywhere else.
Without Plug'n'Play
When you run yarn install (even without PnP), a few things happen:
If you use the offline mirror feature, we download the tarballs from the registry and store them within the offline mirror folder
Regardless of whether or not you use the offline mirror, we unpack all the tarballs downloaded and store their files in the Yarn cache
We then figure out which files from the cache should be copied into which location in the node_modules
We apply the computed changes (a bunch of rsync operations, basically)
With Plug'n'Play
With PnP, the workflow becomes like this:
No changes, we download the tarballs from the registry in the offline mirror (if enabled)
No changes, we still unpack them into the Yarn cache
We generate a .pnp.js file¹
And that's it. There is no other generated file than the .pnp.js file (and the cache, but it already was there before).
¹ As you mentioned, we also generate a .pnp folder (.yarn as of Yarn 2) in the project. This folder is meant to contain two types of data:
Unplugged packages are packages that must be local to the project. Typically, those are the packages with postinstall scripts (we cannot store them into the cache, as the generated artifacts might be different from a project to another).
Virtual packages, which are symlinks created for each package in your dependency tree that lists peer dependencies. Without going into the details, they are a necessary part of the design, and are required to make require.resolve work as before. Those files don't exist anymore as of Yarn 2 🎉
How does it work?
The .pnp.js file contains information similar to the following:
webpack#1.0.0 -> /cache/webpack-1.0.0/
-> it depends on lodash#1.0.0
lodash#1.0.0 -> /cache/lodash-1.0.0/
-> no dependencies
By having those information, the resolution can correctly infer that when a file within /cache/webpack-1.0.0 makes a require call to lodash, then the required files must be loaded from /cache/lodash-1.0.0. It's a bit more complex in practice (we keep an inverse map for improved perfs, we use relative paths to ensure portability, etc), but the general concept is there.
Bonus round: With Plug'n'Play+Zip loading (Yarn 2)
Bonus: With Yarn 2, we're about to improve this workflow even more. This is what it will look like:
We download the tarballs from the registry and store then into the cache (no more distinction between offline mirror and cache - they are the same)
We generate the same .pnp.js file as before
And that's it! As you can see we don't unpack the packages anymore (instead, we use a Node loader to read them from the package archives at runtime).
Doing this has a very interesting property: if both your cache and .pnp.js files are there, you don't need to run yarn install for your application to work! And to ensure you have those files, you just have to add them to your repository and version them as you would with everything else.²
It's very useful, as you don't need to remember to run yarn install after git rebase, git pull, or git checkout, and your CI systems become faster and stabler as they don't need special setup - just clone your application and it'll just work.
² Before someone mentions it - checking-in binary files within a repository is perfectly fine. The reason why node_modules were a very bad thing to check-in within your repository was because of the exponential number of text files, which was putting a huge strain on Git - technically, but also philosophically as code reviews were made impossible.
In the case I described we don't suffer from the same problem, because the number of files is constrained (exactly one file for each package), and reviewing them is very easy - in fact, it's better in that you can clearly see how many new packages are added to your project by a PR!
It imports only the parts of a package you are going to use, making the bloated node_modules folder much, much leaner.
Think about for example having relative big libraries like lodash or ramda when you use only 4-5 functions from them - how much you could save getting only the actually used minimum.
I believe it is not yet 100% fully stable, but still a nice option to keep on your radar :)

how to manage GOPATH for multiple project directories

coming from a java and grails background, (and having written millions of lines of C 30 years ago), I cant see how go can be usable with a fixed gopath on windows.
installing go creates this structure
c:\users\me\go\scr
\pkg
\bin
As you will want to have many go projects it seems they have to be mixed together in the same src/kpg/bin dirs, polluting each other. e.g.
/src/project1/hello.go
/project2/hello.go
/pkg/xx
/bin/hello.exe
Which hello.go will hello.exe run?
Unless I am missing something fundamental, this seems crazy - all completely separate projects are expected to share the same package and bin dirs. It means you dont know which versions of which packages, and which exe files belong to which project, and there is presumably plenty of scope for conflicts. I would have expected a /src, /pkg and /bin for each separate go app (like java or grails or even C), and go path is completely redundant, it can be relative to the current project root (like in grails).
To make matters works, for work, we have to use a different directry, e.g.
d:\work\project3
\project4
\package5
\go_utility6
\go_utility7
So now we have a total of 6 separate directories where go progams live. It is not feasible to change the path every time you switch to working on a different project. I guess the other option is to add the 6 paths to the GOPATH. Presumably, all 7 go projects write to the same pkg and bin dir, which is going to be a disaster.
Is there a tenable solution to this situation (on windows at least)?
If we need to add a PATH to GOPATH for every project, what should the file structure be under each project?
E.g. uner xxx\go_utility6, which is a stand alone command line go app, what should the structure be? does there need to be a src dir in there somewhere? does this dir need gopath to point to it? does it need its own pkg, or should it use the c:\users\me\pkg dir?
UPDATE: When I posted this Go did not have modules support and we built and used a tool called vg. These days the recommended way to go is to use go modules.
I use vg for that, it takes care of keeping separate GOPATH paths per project and it switches automatically when you cd a project.
Your example "which hello.exe" should be used honestly makes not much sense. Two tools with the same name?
Even if both are, let's say, an api, your devops will be happier with more meaningful names.
The bin folder is used for 3rd party tools you install, you so not have to install your project binaries. Except they are tools, but then the name should be meaningful again.
You can get more information about the project structure here: https://golang.org/doc/code.html
Since go 1.8 supports a vendor folder below project folders, it is possible to break the original structure. (imho vendors were not maintainable before 1.8, yes that was crazy)
You might want to use a tool like direnv, which would support your desire to change GOPATH per project.
https://github.com/direnv/direnv
It also has some built in function for adding the current path to the GOPATH.
https://github.com/direnv/direnv/blob/master/stdlib.sh#L355:1
For example GoLang also supports handling multiple GOPATHs and per project GOPATHs. So direnv should also work properly.
In my company we have one go folder right next to our other projects.
Under go/src are our projects. No problem so far, since vendors are in the projects' vendor folders and committed.
The so far best dependency manager I would recommend for go is:
https://github.com/golang/dep
I hope that input helps.
With Go 1.11 Go Modules were introduced. You can use Go Modules to have Go projects outside the GOPATH directory.
Here is an example of how to configure a project using GoModules.

How to install node modules but commit only relevant styles

So, I am setting up a new site and my project's folder structure looks like this now.
foo.com/
index.php
assets/
css/
img/
js/
vendor/
I have added vendor/ for js/css libraries that I must install to keep them separate, since I want anyone who installs my project to install those in vendor from package.json - most libraries contain too many files 99% which I don't want to push to production.
Now once the project is finished, I would like to push the code to production with only the necessary js/css files.
This is where the problem comes. For example, if I install bulma css using:
yarn add bulma --modules-folder ./assets/vendor
It will dump all bulma-related files which are almost 70 into /vendor/bulma/ but I will only be needing one or two css files afterwards, since I will compiles the sass file to css as:
sass vendors/bulmna/style.scss assets/css/style.css
So my questions is: I am assuming this is how every developer does it and there are no documentations I can find that suggest how to do it. Is it safe to ignore the /vendor directory? What if I install vue, font-awesome, bootstrap .. how can I only fetch the files I need but not everything in /vendors folder?
Your question is actually quite broad - however, I'll try to list as much as possible.
Lets say you're building a project from scratch and needed to include vuejs, jquery, fontawesome but only need to include a couple of files.
The issue you're hitting here is module dependency with respect to npm modules. (and there are many different tools that you can use to manage versions on your library dependencies as well as ensuring they are included into your project, i.e. package managers).
Ok - now from here, you may say to yourself
but I only need say, one icon from fontawesome in your final build (dist) and I don't want to commit all my modules into source control
Again, this is where you omit node_modules and other dependent libraries from source control (i.e. include node_modules your .gitignore)
To reiterate
You can install the required library,
add node_modules to .gitignore ,
bundle those libraries into a vendor single file to be consumed by your users (can be via browserify/webpack/rollup/gulp/grunt/yarn etc).
generate bundle within npm script
Now you may ask further -
Why would I use any of those tools? - they're distracting me from simply copy/pasting vendor libaries into my source control.
Build tools were created to
streamline the developer pipeline so that you DONT have to copy/paste vendor libaries into a vendor folder.
ensures that all files are bundled to the client automatically
allows you to keep track/restrict library version updates/ when required via package.json
allows you to add other build steps (such as minification, md5hash versioning, compression, code splitting, asset management to name a few).
Now lets break down the original question here:
How to ensure other developers get everything they need when cloning the repository
how do I ensure I can provide only the necessary files to the end user (if I only use specific parts of vendor libaries?)
1. How to ensure developers get what they need
Again, to reiterate above, adding devDependancies and .gitignoring allows you to only add the necessary files to your project.
2. How can I ensure clients get what they need without bloating request files?
This is where build tools such as webpack, browserify, gulp, grunt, rollup, attempt to achieve. This is because with some libraries that exceed in file size of 200kb minified, you may need to separate these files into different client requests (and as such, not demand the user to request one large file, which was symtomatic of browserify projects).
The second technique you will need to be aware of, is with specific libraries, you can use import mdn link where you can require one function/class from a dependant library (which further reduces file size).
Another technique is using less import statements (which can extract less functions/styles similar to above, but this isn't currently supported in SCSS). for SCSS, you're basically left with copy/pasting the necessary styles into your base scss and that'll save you space as well.
EDIT
How to create a bundle from npm install libaries
From the comments you've mentioned above (about not wanting to include a tool into your workflow, there's no point outlining any one particular strategy - you can find answers/tutorials online about how to setup gulp/browserify/webpack for your particular needs).
However, As you are currently using yarn - I'll go into details about that.
Firstly, yarn is a package manager (like npm). All it does with the --modules-folder is install the package into the specified folder, that's all. So we don't really care about that (since it's doing the same thing as npm). (i.e. your vendor folder is the same as node_modules in many respects).
We could use
webpack
gulp
grunt
rollup
browserify
brunch
(All build tools that essentially allow you to bundle all those packages into a single entry point to be packaged to the client).
I won't go into how, because that is a process you can find online, and from the above comments, I can tell you don't particularly care either.
What you are looking for is a zero-config javascript build tool. (Extremely out of the scope of your original question, and i'll only answer that in a separate Q&A).
I'd try Googling on "tree shaking CSS" to see if that gives you something.
Maybe something like: https://github.com/jacobp100/es-css-modules
Rollup plugin may be useful. It works for js, with postcss, the link says it works with css also.
https://code.lengstorf.com/learn-rollup-css
Have a look at Pancake. It has been built specifically for the purpose of moving only those files out of the node_modules folder that you need. I wrote an article about it here: https://medium.com/dailyjs/npm-and-the-front-end-950c79fc22ce
(probably not an answer but a good tip)
PS: I am the author of both, the article and the tool so with clear bias :)

Golang project structure in an application versus a package

My organization uses Rails to develop its app but I'm attempting to re-write one of our back-end processes in Golang because it's much quicker.
I've structure my application with our company a namespace for my app (example.co), and a subfolder for each of the packages within my app.
Each library that I've included (e.g. sqlx, etc...) also has it's own folder.
src/
github.com/
jmoiron/
(sqlx package files)
example.co
my_app/
(my app package files)
model/
(model package files...)
However looking at other packages like sqlx, it appears they scrap this directory structure entirely and put all their files in the root directory
Is this because I'm writing an application and sqlx is a package that's meant to be included in other applications? Or is it just a difference in preference since there's no real accepted "standard"
I did this too on my first project. I have since learned:
the $GOPATH/bin/ pkg/ src/ layout is constructed by go get and similar commands
you can organize your .go files as a single flat project dir or with subfolders (caveat: all .go files in the same folder must have the same package name)
put other people's code in a /vendor directory inside your project root, if it is code your app needs to work (google this, it's the worst part of go imo)
put your own project under your gopath, symlink to it if you want it more accessible
So I would imagine your code could look something like:
/Users/user2490003/MyGoPath/
â–¾ src/github.com/user2490003/myproject/
â–¾ model/
user.go
â–¾ myapp/
myapp.go
â–¾ vendor/github.com/jmoiron/sqlx/
sqlx.go
main.go
Import the full package references, like this:
// main.go
package main
import (
github.com/jmoiron/sqlx
github.com/user2490003/myproject/myapp
github.com/user2490003/myproject/model
)
I would recommend to start with a layout that seems logical and works at the present moment and then refactor/restructure as needed when your applications grows and evolves.
Using your company namespace is reasonable - I would consider creating a directory for your app underneath it (such as company.co/my_app) and inside of it, subdirectories for library packages (for example, company.co/my_app/db etc.) as well as the cmd one that would contain directories for the actual executables (package main programs) that you want to produce: cmd/exe1, cmd/exe2 etc. This will allow you to have multiple executables as well as multiple library "subpackages" inside of the my_app which can be included independently with the corresponding import path.
Each library that I've included (e.g. sqlx, etc...) also has it's own folder.
If you are ok with using the latest version of dependencies from Github, you don't have to include the dependencies' code into your repositories but instead install them with go get into the build area. If you want to build from a local copy - and for corporate usage, it may be preferable for stability and audit track - you should put them in a vendor subdirectory, for example company.co/my_app/vendor/github.com/jmoiron/sqlx. This way you have control on when you upgrade to a newer version of the dependencies and assurance that the upstream changes will not break your build or otherwise affect your programs without your knowledge and until you have a chance to do thorough testing.

How should I structure a simple Go project?

I have a pretty simple Go project that I'm trying to restructure so that it follows the normal Go project structure (and so I can run go build).
I currently have two source files, both with package main. All the files, including a few text configuration files that my program needs at runtime.
So right now, it looks like:
<project_name>
- main.go
- source2.go
- config_file.txt
I can run go build when I'm in this directory, and it creates one binary (named <project_name>. This works fine, but I'd like to set this up to better follow the Go standard package structure (specifically so that Intellij IDEA will recognize it as a valid project).
Right now, I have the entire <project_name> directory in Git, and I'd like to keep it that way.
I tried putting the source files in a folder called src, but then go build says there aren't any source files to compile.
How should I structure this?
EDIT:
Figured out the issue with putting stuff in src/: I need to run go build <project_name>.
I'm still wondering if there's a way to set up a project without a global GOPATH. I have all my projects under one folder, with a subfolder for each project (not all the projects are Go project). I'd like to keep that system.
What I want is:
projects/
- project 1/
- src/
- bin/
- pkg/
- project 2/
- src/
- bin/
- pkg/
Then I'd like to be able to run go build <project_name> (while I'm in that project's directory) and have it compile that project. Is that possible?
The "canonical" way to organize your Go code is described in How to Write Go Code. It is explained in a less formal way in this blog post. This concept is kind of contrary to what you have in mind - you have a workspace directory, specified by the GOPATH environment variable, and the source code of all projects resides in subdirectories of the "src" directory of the workspace. You can have multiple workspaces if you specify several directories in GOPATH.
I would suggest you give the "recommended" way to organize your code a chance, maybe it will grow on you. It may seem a bit unusual, but it has its advantages. If you find out you absolutely can't live with it, you can still work around it, e.g. by setting GOPATH dinamically in a script.
As for the Golang IDEA plugin, the last version I tried some time ago didn't yet support this project structure, but newer versions may have changed that. In fact, one of the plugin's authors (dlsniper) has added a comment to the above blog post giving examples of alternative project structures that still use a global GOPATH.

Resources