after optimizing a require.js project (pushing everything into one "big" .js file), is there any way to circumstance the need to include the require.js file (which then only loads one single .js file) and load the compiled file directly instead?
You can use a light weight AMD loader like Almond. You will still need a loader anyway as your compiled JavaScript still use define and require.
Related
I'm struggling to find a "quick" way to transition some legacy javascript files from assetic to webpack. I (think I) need to find a way to bundle a set of javascript files by simply concatenating them and not having webpack wrap it in a jsonp.
Our platform is built in Symfony, using twig templates and we've got most of our legacy javascript files loaded using assetic (it simply concatenates, and minifies), we've got newer javascript/typescript files bundled with webpack.
Naturally I want to remove all assetic dependencies and use webpack to bundle the old javascript. However, due to the way that webpack produces the bundles, it gets wrapped in the jsonp and any functions/variables defined in those javascript files are not available in global scope.
In an assetic world, our twig files are littered with these:
{%- javascripts
'%kernel.root_dir%/../vendor/twbs/bootstrap/js/bootstrap-transition.js'
'#MyBundle/Resources/js/legacy-1.js'
'#MyBundle/Resources/js/legacy-2.js'
filter="?uglifyjs2"
output="js/compiled/page-one.js" %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Which concatenates and minifies them all. I'd like to replace this with a similar webpack version.
I've identified some approaches, but I'm not sure any of them are the best.
Use script-loader to get the scripts to load in global scope - Since script-loader uses eval which is disabled using CSP, this is out of the question
Rewrite each javascript file, exposing the members on the window. - This would probably be the easiest option but I really don't like the idea, and it goes against best practices.
Rewrite each javascript file, exporting the members, then use the expose-loader to load the files, then go through all the twig files and update the references to the members with the global namespace. This would take a lot of time, and I'd prefer not to do this if at all possible
I figured that I could simply configure a queryParameter and the file-loader to load each one, but I'd need a script tag per resource, and would lose out on the bundling nature. (I use a Symfony webpack bundle to generate an entries list for webpack, and provide twig functions for loading entries at runtime from the cdn)
<script src='{{ webpack_asset('%kernel.root_dir%/../vendor/twbs/bootstrap/js/bootstrap-transition.js?asFile') }}"></script>
<script src='{{ webpack_asset('#MyBundle/Resources/js/legacy-1.js?asFile') }}"></script>
<script src='{{ webpack_asset('#MyBundle/Resources/js/legacy-2.js?asFile') }}"></script>
So I'm looking for a way to concatenate the files together. Creating a separate entry file, and loading that as a file wouldn't be good enough as the requires/imports wouldn't be resolved.
I understand the webpack-concat-plugin would require me to define all of the various files to concat up front in the webpack config, which isn't really possible.
I haven't come across a loader that would replace the import '#MyBundle/Resources/js/legacy-2.js' with the content of that js file - but maybe I'm missing something.
I wonder if after all of this effort trying to find an easy solution is greater than the effort to rewrite the legacy javascript to use modules...
I found the following answers but they don't really help me:
Webpack - How to load non module scripts into global scope | window - This assumes I can define the files to concatenate up front. I have almost 100 different includes using assetic, almost all of them use different files.
Webpack - How to load non module scripts into global scope | window - eval is disabled by our CSP
Expose javascript globals bundled via webpack - As I mentioned, I don't really want to create 100 'entry' files just for this, and the webpack-raw-bundler also requires everything to be defined up front in the webpack config file.
Is it correct to think that loaders actually transform other types of code into javascript code? So a CSS-loader actually transforms CSS code into Javascript so that the JS file that imports CSS actually gets CSS transformed and then injected into that JS file when you webpack builds out your bundle?
This isn't true for all loaders. The idea behind Webpack loaders is to provide multiple ways to handle some resource or asset - whether that's a javascript module, a CSS stylesheet, or an image. The loader is responsible for parsing/processing the resource, which might do any of the following:
Transpile it into another language (e.g. babel-loader)
Copy the resource to a specified location and provide the new location as the imported value (e.g. file-loader)
Ignore the resource entirely (e.g. ignore-loader)
One thing that makes webpack so powerful is that these loaders can find more dependent resources inside the resource they're processing, and hand off to other loaders. So it's plausible to import an HTML file within your javascript, and that HTML file could reference another javascript file, which could then be loaded too.
Using gulp, what is a proper way to inject one js file into another?
I know about gulp-browserify, but that wraps each require'd file in it's own IIFE so variables are no longer global and, unfortunately, I need them to be global.
I know I can also concat all JS files into one, but I would like to generate separate JS files.
Is there a way to simply include the contents of one file within another where I can specify the concatenation in the JS file itself instead of in Gulp's configuration file?
The Answer is below the question:
Maybe I don't understand the whole RequireJS thing fully,
but here is my problem:
I got a set of files like that:
sub
sub1.js
sub2.js
main.js
In all of the files in sub, i use the define() function to define modules. In the main.js, i use the require() function to load all modules. All of this works.
Now when i run the optimizer (r.js) on the main.js, it just takes the content of all files and puts it into one file. Yes, i can then use this optimized file to do the same as what i could do with the multiple files.
All good, no error.
Now my question: In that optimized file, it still uses RequireJS. Can i optimize it to the point, where it doesn't use RequireJS, where it's just the functions put together?
Answer
You can only include RequireJS into your optimized file by setting the include option to "requireLib".
Are you trying to load the file in the script tag w/o using data-main + require.js? OR, are you trying to render the file so that RequireJS is no longer used at all? I suspect it's the latter, which is not possible. If the former, that is achieved by bundling Require in via a build file option: http://youtu.be/m6VNhqKDM4E?t=12m44s
No you cant. The point of the r.js is to compile all your dependencies situated in multiple files into one. So even after compiling the modules are still AMD modules, but now without the need to load them separately. And the modules still need an AMD loader to get work. The only thing you can do after compiling is to use a more lightweight loader loader like Almond
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.