I'm fairly new to webpack.
From a YouTube tutorial (Academind) I watched, the guy teaches the user to include the HTML file in the entry .js file. From what I understand, webpack will then use HtmlWebpackPlugin to extract the required HTML file out, then inject either as a file or code into that HTML file. Is my understanding correct?
I'd like the above question answered, but that's not the main question. The main question is the reason for going through such pain.
Can't I just have the .html files copied to /dist and have each .html file have bundle1.js, bundle2.js, etc., in them?
That tutorial required html file because it was thought that it was easier to let webpack (HtmlWebpackPlugin) insert all the script tags for the bundles automatically, without having to do that manually.
You can also not require that, and add the template property on HtmlWebpackPlugin. That will do the same thing.
You can also copy to dist, of course. But that would require you to insert manually script tags on your html. That starts to get worst when you have hashes on your filenames.
Related
Two days ago I've learned about webpack loaders. After 6-7 youtube videos and several hours of practice I know how to use them. But not a single tutorial explained, why should I. They say "We can just add tag and add css there, but let's do it using loaders". So now I know what loaders are and how to use them. But... Why? What benefits are here? What can I do with webpack css- and style-loaders and cannot using ? Or is it better for performance to have css written is js file? What bothers me more is to use loaders for img files, fonts and other files. All loaders do in this case is just change the names and put them into "dist" folder. Why cannot I just put the images I need into that folder manually, why use loaders (I don't speak about compression of files here, because I'm not sure yet if I am able to compress imgs with loaders). So my question is, why loaders? Especially, why loaders for imgs and other files, if I just might as well put them into dist folder myself? What are benefits which I cannot see now
Well you do so you can bundle them up. For example, say you want to work with SASS. You build up your SCSS code, now you have to produce the CSS file and add it up to your html files. Now, if you have a loader, webpack can compile the CSS file for you and bundle it up with your javascript code. So now you don't have to manage style tags as the javascript code will do that for you. Say you have typescript code. That also needs compiling and probably bundled up.
Do you need loaders? They are not exactly required but the alternative is doing everything manually. As per CSS, fonts, images, etc.. You have to understand that Webpack is all about creating a bundle. So it can pick assets and bundles them up. Could you do it manually? Also yes, but then again, that's what Webpack does.
The following question was rewritten, because I have now a working solution, but no answer to the question above.
The repository that shows different scenarios how to use resources packed with webpack is named example-webpack-dynamic-resources. It contains 3 modules:
inline: a solution, but not useful in my context (many resource files)
file: a solution by using the plugin webpack-require-from
public-path: no solution yet, shows how I would like to use __webpack?public_path__.
I think I have read any resource about webpack and publicPath and __webpack_public_path__, but I don't get it to work. I try to dynamically change the path to static resources, but it fails.
Here is my context:
I build a Javascript library that will be used on web pages (HTML, CSS, Javascript).
It provides a lot (>100) static resources to small image files, combined > 500 KB. Only a fraction of it will be used by the user looking at the web site.
Therefore I would like to pack the CSS into the bundle, but keep the image resources in a directory located on the server somewhere. The default path to it will be /img.
As long as I use the same structure (which means, images only under ROOT/img/**, everything is ok.
But the users of the library should be able to configure the path to the image resources on their will.
You will find all relevant files in my example repository example-webpack-dynamic-resources in the module public-path-resources.
webpack.js: Use file-loader for images, which are referenced in CSS files. CSS will be inlined by style-loader and css-loader.
src/public-path.js: Define the global variable with a default (no environment variable).
src/index.js: require first public-path, then the logic.
examples/exam1-root/index.html: Tries to use the assets in the sub directory lib, sets the value therefore to __webpack_public_path__ = '/lib/. Not working.
examples/exam2-different-dirs/index.html: Moves the library to a different dir (not relevant), but uses the originally defined directory pgnv-assets for the assets. Working.
examples/exam3-non-standard-dirs/index.html: Try to use instead my-assets as directory for the assets. Not working.
How could the __webpack_public_path__ defined at runtime in the index.html file?
I am using react starter kit for client side programming. It uses react and webpack. No index.html or any html to edit, all js files. My question is if I want to load a vendor js lib from cloud, how to do I do that?
It would be easy to do that in a html file. <script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>
However, in js file, it only uses npm installed packages. How can I import the above lib with no html file? I tried import and require, they only work for local files.
update 10/21/15
So far I tried two directions, neither is ideal.
#minheq yes there is a html file sort of for react start kit. It is html.js under src/components/Html. I can put cloud lib and all its dependencies there like this:
<div id="app" dangerouslySetInnerHTML={{__html: this.props.body}} />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>
<script src="/app.js"></script>
<script dangerouslySetInnerHTML={this.trackingCode()} />
</body>
Good news is it works, I don't need do anything else in js file, no import or require. However, now I have two jquery libs loaded in different ways. One in here, the other through npm and webpack. I wonder it will give me trouble later. The react-routing I use give me 'undefined variable' error if I type a none home path in browser window due to the server side loading I guess. So this solution is not very good.
Use webpack externals feature. This is documented as: link. "You can use the externals options for applications too, when you want to import an existing API into the bundle. I.e. you want to use jquery from CDN (separate tag) and still want to require("jquery") in your bundle. Just specify it as external: { externals: { jquery: "jQuery" } }."
However, the documentation I found a few places are all fussy about how to do this exactly. So far I have no idea how to use it to replace <script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script> in html.
externals is not intended to let you do this. It means "don't compile this resource into the final bundle because I will include it myself"
What you need is a script loader implementation such as script.js. I also wrote a simple app to compare different script loader implementations: link.
var $script = require("scriptjs");
$script("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", function() {
$('body').html('It works!')
});
You can create a script tag in your JS as
$("body").append($("<script src="https://forio.com/tools/js-libs/1.5.0/epicenter.min.js"></script>"))
There is one html file that is definitely being used to serve to users with your js bundle attached. Probably you could attach the script tag into that html file
Use webpack's externals:
externals allows you to specify dependencies for your library that are
not resolved by webpack, but become dependencies of the output. This
means they are imported from the environment during runtime.
I have looked around for a solution and most of all proposals were based on externals, which is not valid in my case.
In this other post, I have posted my solution: https://stackoverflow.com/a/62603539/8650621
In other words, I finished using a separate JS file which is responsible for downloading the desired file into a local directory. Then WebPack scans this directory and bundles the downloaded files together with the application.
I am attempting to use yeoman to scafold a web site, my website includes references to files such as images/foo.kml
Running Grunt results in these files being filerev, i.e. the file images/foo.kml is copied to the dist directory but now called images/3333.foo.kml.
The only problem is that usermin task does not replace the references to images/foo.kml in the requested javascript file, but it does manage to process all the references to css and javascript files.
References to images, css and javascript files are normally listed by html tags, eg , etc. In my case I am making a programmtic request to a kml file which is used by a bit of add hock javascript, can usermin deal with type of problem? Or would I be better off putting all of the files that are going to be accessed by a javascript application in a different directory and ensure that references to these files are not subject to filerev?
Bottom line I was using OpenLayers to process the kml files, as the files are not used my img tags and only by a Java script program, the file name has to remain a constant. Since the uglify task has no concept of understanding a file name within a block of Javascript.
My solution was to change the grunt file so that my kml files are copied from the app to the dist directory.
I'm wondering if someone can check my understanding of what the intended purpose of HTML5Boilerplate js directories. I understand that main.js is where I'm expected to place all site specific javascript that I author. Plugins.js is where I would place all jQuery plugins used. Both main.js and plugins.js will be concatenated and minified by the build process. Vendor.js holds javascript libraries. This directory will be minified (unless it is already minified) but not concatenated.
If this is true, then my question is where should something like cute slider which has a modular structure be placed? I'm thinking I want it to be minified and concatenated so it shouldn't go in the vendor directory. I don't believe I can add cuteslider's javascript to main.js or plugins.js without destroying it's modular structure. Should I create a new directory, and call it something like apps, to hold cuteslider code and then modify the build code to minified and concatenated it?
Here is a snippet of cuteslider's code structure
cute
cute.2d.module.js
cute.canvas.module.js
cute.css3d.module.js
cute.gallery.plugin.js
cute.slider.js
cute.transitions.all.js
First you have to consider cuteslider as a plugin.
Add the required files to make the plugin working (cute.slider.js, cute.transitions.all.js and respond.min.js) in the plugins.js.
Then add the js to load the slider into your page in the main.js as
$(document).ready(function() {
// code here to load cuteslider
});
The modular look have to be set only in the main.js file.