I noticed that Bootstrap and Normalize.css both have a "style" field in their package.json.
Why do they have this? If I had to guess, it's to allow users to import the defined stylesheet as easily as doing require('bootstrap'), but that doesn't seem to be the case.
From Techwraith's pull request that added it to Bootstrap:
Many modules in npm are starting to expose their css entry files in
their package.json files. This allows tools like npm-css,
rework-npm, and npm-less to import bootstrap from the
node_modules directory. [...]
It's actually not written anywhere but in the code for these modules
right now. We're hoping to get this standardized at some point, but
we've all reached this convention separately, so I'm inclined to just
go with it. [...]
If you want to read about this style of css development, I wrote a
thing:
http://techwraith.com/your-css-needs-a-dependency-graph-too/
There's also support in other tools, such as the browserify plugin parcelify:
Add css to your npm modules consumed with browserify.
Just add a style key to your package.json to specify the package's css file(s). [...]
Parcelify will concatenate all the css files in the modules on which
main.js depends -- in this case just myModule.css -- in the order
of the js dependency graph, and write the output to bundle.css.
Related
I start learning webpack , node , and react and I am bit confused about some basic staff.
Does webpack bundle whole react.js + my javascript files into one output file, so when deploying to production I don't need to install node packages used in project (assuming that they are added to webpack.config.js file) ?
If above is right:
On my server I just need to place index.html + output from
webpack ( bundle.js) ? ( In simple scenario) ?
package.json will be used only on development side ?
You only need index.html and the bundle.js (or any name you gave the file) for the app to work, provided that you are not using any local assets. You don't need to include node modules. Package.json should tell you what to include in your project so that you don't have to include node modules whenever you want to upload your project along with few other decalarations.
The way Webpack works is that you specify one or more entry points and one or more output files. Webpack then reads the entry point and also traverses through the import / require statements recursively. It then generates final bundle file(s) which includes all the traversed files.
Yes, Webpack outputs everything in the the bundle.js file(s). You can configure multiple output bundles. So, you just need HTML and output bundle to deploy the app.
The package.json specifies the packages upon which the app depends, apart from several other things. While traversing through the entry points, webpack will also include the packages specified in import / require. Function of package.json is to tell npm to install those packages.
I am looking for information on how to bundle dependencies with Webpack. Haven't been doing front-end development much recently and behind the latest trends.
(a) I would like to bundle x number of dependencies with Webpack, but
I do not wish to specify an entry point. Such that if the bundle was
require'd, nothing would execute.
(b) This has probably nothing to do with (a) - ideally I could bundle
them as AMD modules. Basically, would like to take NPM modules and my
code and convert things to AMD.
I am guessing that the above can be accomplished through some webpack.config.js configuration, but I haven't see anything online demonstrating how you can bundle deps with Webpack without specifying an entry point.
You have to specify an entrypoint, otherwise Webpack won't be able to parse your modules and statically analyze the dependencies.
That said, you don't have to directly specify an entrypoint in your configuration. You can use the webpack --entry path/to/entry.js $OTHER_ARGS and then require all the dependencies therein, or you could use the configuration can and specify all the required modules:
{
entry: ['react', 'foo', 'bar', './ours/a', './ours/b']
}
In any case, the way Webpack evaluates your modules during runtime does not make these modules readily available. I suspect what you actually may be interested in is creating library targets, which are compiled independently and then reused in other Webpack builds.
Here is a nice article that explains the approach in detail and then you can refer to the official documentation.
Ive just published my first package (a react component) to npm but im having some trouble understanding the difference between what the lib directory is compared to the dist.
Currently I generate both lib and dist however my package "main" points to the dist unminified js file which has been built using webpack and output as UMD. The lib folder is built using babel taking the src and outputting to lib.
The dist folder contains both [unminified/minified].js files as well as [unminified/minified].css files.
My main confusion is with the lib folder since imports from there currently wouldn't work seeing as I just transform src -> lib meaning the scss references are still there and the scss files aren't transformed either.
I use CSS Modules (css-loader, styles-loader, postcss-loader etc) to generate my CSS files and this is where the confusion is since, wouldn't I also need to use webpack to generate my lib folder seeing as the scss files/import references need to be transformed to css?
Are you meant to have both lib and dist or is the UMD build in dist fulling the same purpose as that of having a lib folder?
If you are supposed to have both how would I achieve this, since I couldnt find any info regarding generating the lib folder when using CSS modules within your js files and still maintaing the same folder structure of that of src (while still generating dist)?
Usually the dist folder is for shipping a UMD that a user can use if they aren't using package management. The lib folder is what package.json main points to, and users that install your package using npm will consume that directly. The only use of the lib as opposed to src is to transform your source using babel and webpack to be more generally compatible, since most build processes don't run babel transforms on packages in node_modules.
As far as handling the style imports, it's probably a good idea to not import scss or css files in your source js that you export. This is because node can't import styles like that by default. If you have an example that demos your component, it makes sense to import the styles there. The common pattern is to publish minified and unminified css in the dist folder, and in your documentation tell the consumer to explicitly import the css file using whatever technique they prefer. I took this approach with redux bug reporter if you need an example. Hope that helps!
In general lib refers to libraries that are included in a package, dist on the other hand are distribution files for your project. As an example you could write a bunch of javascript and include jquery (which is a lib) and then when they're all bundled up you have a single dist file.
Ok think I found out how to do this. There is a babel plugin that allows you to use webpack loaders when running babel (babel-plugin-webpack-loaders). Thus my CSS mapping is inlined within the js file and the mapping hashes used are also the same as that used when building dist. Yay!
In the data-main require js file, we write like this:
paths: {
jquery: 'lib/jquery',
underscore: 'lib/underscore'
}
What I did was manually download the row JS library files and make "lib" folder and move the file into the folder and change the file name if necessary.
I use Nodejs for server, and I am wondering if there's any tool to create these client-side Require path files automatically from the installed Node-Modules. Browserify does a similar job if I don't user Require (creating one JS file, and call it in the other browser JS files.) But it seems like Browserify cannot be used as a path in Require.
Any thoughts? Thanks.
An alternative solution (to browserify, with which I'm not familiar) is to use bower for managing client side libraries. It is similar to node/npm, but is geared towards browser libraries.
It will not copy or rename libraries, because that step isn't necessary. Instead the libraries will be placed in a directory called bower_components. The paths config would look like
paths: {
jquery: "../../bower_components/jquery/dist/jquery",
bootstrap: "../../bower_components/bootstrap/dist/js/bootstrap",
...
}
(the actual number of .. in the path depends on values of other requirejs options).
In development, when all dependencies are loaded asynchronously as separate files they will be loaded from bower_components and requirejs optimizer will find them there when generating the optimized single source.
Adding the dependency paths to the config file can be half-automated with grunt plugin grunt-bower-requirejs. The idea is that after a library is installed using bower install LIBRARY it's path can be added with grunt bower.
I've installed backbone via npm, it is placed in node_modules folder (not in web root) how can i include it in my index.html file?
It's possible to write front-end code entirely based on CommonJS (i.e. Node-style) modules.
If you install front-end dependencies through npm you can use a package bundling tool like Browserify to bundle all dependencies into one file. This way you can use the browser-dependent packages in the same way you use server-side packages: with Node's require function. You just require a module (either in node_modules dir or a regular file) and work with it.
Base use of browserify is really simple: Just do browserify clientcode.js > webroot/clientbundle.js, where webroot is your web root. Then include clientbundle.js in your html file.
clientcode.js should be the client's "main" script, comparable to the "app.js" (or similar) of an Express app or so. It can be as big as you want, but you could just as well use it only as bootstrap code to run functions defined in other CommonJS modules.
Note that you can easily mix browserified dependencies with regular dependencies. Any scripts that you include beforehand (say a non-browserified jquery) will just become a global, and browserify does not prevent you from accessing globals.
Beware though: Some packages distributed via npm based on client-side libraries do not conform (entirely) to CommonJS spec. Some may not export anything, some may (unexpectedly) create globals, etc.
See also Backbone app with CommonJS and Browserify .
Some alternatives to browserify:
https://github.com/michaelficarra/commonjs-everywhere
https://github.com/medikoo/modules-webmake
https://github.com/webpack/webpack
I haven't tried them though.
While the idea of using npm for both backend and frontend may sound tempting–it certainly did to me–try Bower or Ender.js instead for frontend dependencies. I personally prefer bower, because I can more easily include it into my requireJS module structure. It will keep you from foaming at the mouth with frustration.
Front-end dependency I would recommend using Bower. There are many components available for you to use and they are really easy to setup.