I'm getting a strange error from webpack in my prod environment in the following line only on FF. I've tried Chrome, Safari and there are no issues.
function __webpack_require__(moduleId) {
...
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
}
If I break on that line and reload the page the issue does not happen which leads me to think it some kind of race condition on a file which is loaded.
I have 4 webpack output files in the following order.
<script type="text/javascript" src="/manifest-4.e05278c43f895122ca44.js" async=""></script>
<script type="text/javascript" src="/vendor-2.e05278c43f895122ca44.js" async=""></script>
<script type="text/javascript" src="/main-0.e05278c43f895122ca44.js" async=""></script>
<script type="text/javascript" src="/bootstrap-3.e05278c43f895122ca44.js" async=""></script>
I've looked at Github & SO for similar issues but don't think they directly relate to my issue.
[UPDATE]
Debugged the exact moduleId to be 49. Contents of main bundle file is empty for the 49th module which means it must be in vendor bundle. Suspect the loading speed of main and vendor bundle might be causing some issues.
Figured out the answer myself.
As suspected this was because vendor bundle loading after main bundle. Even though vendor bundle is specified before main there are couple of reasons causing this.
async attribute might cause race conditions when fetching the bundle
Apart from async we were also preloading the main bundle
We removed both as we did not have any use for them.
Related
Calling on the react experts haha.
I am trying to import/include some external javascript files into my React project, these js files cannot be changed or edit as per instructions from my company, as this is a base for many application that uses them.
For reasons i wont be putting the real filenames and folders.
There is a folder in my public folder called "testModules", so path is public/testModules/
all the files / 3 files that i need to include is in there.
What i have tried so far.
In my index.html file at the bottom i have tried the following
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test1.js"></script>
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test2.js"></script>
<script type="text/JavaScript" src="%PUBLIC_URL%/testModules/test3.js"></script>
and
<script type="text/JavaScript" src="./testModules/test1.js"></script>
<script type="text/JavaScript" src="./testModules/test2.js"></script>
<script type="text/JavaScript" src="./testModules/test3.js"></script>
and
<script type="application/javascript" src="./testModules/test1.js"></script>
<script type="application/javascript" src="./testModules/test2.js"></script>
<script type="application/javascript" src="./testModules/test3.js"></script>
and
Then i have also tried using the ScriptTag plugin "react-script-tag"
with the same examples as above, but instead of %PUBLIC_URL% i used process.env.PUBLIC_URL
When i try any of the above it works on my local development env. For example running npm run start and opening on localhost
But as soon as i move to application to a live server i get the following err
Refused to execute script from 'https://test.com/testModules/test.js'
because its MIME type ('text/html') is not executable, and strict MIME
type checking is enabled.
For all the files i added.
Now i open up my dev console and i can see the scripts are appended/included in the body at the bottom.
What is going on and how can i fix it.
Thanks You
If you wouldn't like to make any improvements to your deployment architecture, then you should pretty much talk to "your backend devs" so that they configure the web server so that this particular route would emit a different MIME type while serving this particular static file.
Alternatively, if possible, you could use Webpack to statically link the third-party code base to your React project so that they are distributed together. This way, if you use any implementation of Javascript modules, you will eliminate this crutch of your library being visible at the scope of the HTML host and this might bring improvement to your codebase.
I want to start using Webpack.
Currently, in one project I have the next lines:
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
<script defer src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script defer src="/js/doubletaptogo.js"></script>
<script defer src="/js/init.js"></script>
I guess the following:
I should not download modernizr neither jquery because both are downloaded from their respective CDNs.
DoubleTapToGo is also a library and it is a minified local file. It is expressed via an immediately invoked function expression. So I should convert it into a module using module.exports, but I don't know how to do that and if I really should:
init.js should require DoubleTapToGo as a module, to produce just one file and finally have 2 libraries and 1 local JS file.
Please correct me.
Thank you in advance.
doubletaptogo.js has the following content:
;(function($,window,document,undefined){$.fn.doubleTapToGo=function(params){if(!('ontouchstart'in window)&&!navigator.msMaxTouchPoints&&!navigator.userAgent.toLowerCase().match(/windows phone os 7/i))return false;this.each(function(){var curItem=false;$(this).on('click',function(e){var item=$(this);if(item[0]!=curItem[0]){e.preventDefault();curItem=item;}});$(document).on('click touchstart MSPointerDown',function(e){var resetItem=true,parents=$(e.target).parents();for(var i=0;i<parents.length;i++)if(parents[i]==curItem[0])resetItem=false;if(resetItem)curItem=false;});});return this;};})(jQuery,window,document);
I'm confused about my r.js optimised script. I imagine the answer to my question is in the documentation but I think I'm going doc-blind from staring at it too long.
My application has a directory structure like this
-index.htm
-js/app.js
-js/init.js
-js/appname/*.js
When in non-optimised mode index.htm contains the following line:
<script type="text/javascript" data-main="js/app" src="js/lib/require-2.1.11.js"></script>
and everything works fine. My abridged js/app.js script looks like this:
requirejs.config({
baseUrl: 'js',
paths: {
...
}
});
require(['init']);
When I build the optimised script I specify js/app.js as the mainConfigFile and everything builds as expected. However when I update my script tag's data-main attribute to the build product my application doesn't initialise.
If I manually execute require(['init']) in the console it starts up as expected. Because r.js is using js/app.js as its config file that doesn't get included in the optimised script, which means my require(['init']) also doesn't get included.
I thought I could fix this by moving require(['init']) to the end of js/init.js and this does fix the optimised build (it initialised as expected), but now that the call isn't in js/app.js the non-optimised version never initialises. If I include the call in both files I get an error.
How can I ensure my first module is required after either the optimised or non-optimised file(s) are loaded? I don't understand how I'm supposed to make that first call after my first module's dependencies have fully loaded.
Because r.js is using js/app.js as its config file that doesn't get included in the optimised script
Well, then modify the build config you pass to r.js so that js/app.js is included in the final optimized bundle. There's nothing that forbids you from including the file you point to with mainConfigFile in the final bundle.
I have developed an application using RequireJS, with no optimization layer - Require downloads each file separately. Here is the outer markup:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
var require = {
//some basic config
};
</script>
</head>
<body>
<!--snip-->
</body>
<script type="text/javascript" data-main="main" src="scripts/lib/require.min.js"></script>
</html>
This functions without any issue, but with 100+ files the load time is really getting up there. So, time to introduce r.js optimization! I use node and r.js to create a combined file, and change data-main="main" to data-main="_build/main".
I get the following error:
Error: Mismatched anonymous define() module: (the entire body of crossroads.js)
Thoughts:
There are no manual / out-of-band define() calls or anonymous modules. Everything goes through the optimizer into this one file.
This isn't even our file - it's crossroads.min.js, which Require is able to handle just fine when the optimizer isn't involved.
I am still digging, but hoping someone can save me some time here.
TL;DR; Use the unminified version of crossroads.js, since you are doing a r.js build it will already compress the source file.
crossroads uses an unnamed define and is wrapped into a custom UMD (universal module definition). The minified version won't work well since r.js can't add the proper module name.
before minification:
(function(define){define(["signals"], ...
after minification:
(function(a){a(["signals"], ...
r.js can't figure out what a means, it only looks for define calls.
I can't find an answer to this anywhere. Does this need to be done or does the optimiser do this somehow?
If a minified requirejs file became very large would it be suitable to break my_main.js down and possibly use my_main1 and my_main2?
<script type="text/javascript" data-main="my_main.js" src="scripts/require.js"></script>
You specify which modules you want via your "require" and "define" calls...
Your index.html will have a tag such as:
<script type="text/javascript" data-main="my_main.js" src="scripts/require.js"></script>
Inside "my_main.js" you'd do something like:
require(["module1", "module2"], function(module1, module2) {
});
which would load in module1 and module2.
When you decide to optimise your code, the optimiser will look through all the modules you load and all their dependencies and put them in a single minified file. You'll only need to load that minified file in your index.html in an optimized build.