โ
The origin of this article is to use the Qiankun framework in the development environment. The parent application Failed to load the child application. The server responded with a non-JavaScript MIME type of “text/html”. Strict MIME type checking is enforced for module Scripts per HTML spec fail to load the module script: the server responds with a non-javascript MIME type of “text/ HTML”. And that’s the question that got me thinking, what’s the problem?
โ
1. ๐ค thinking
โ
Based on analysis and location, I suspect it was because I used –modern mode compilation in vue-CLI for my child application, which builds two JS packages, a native ES6 package for supporting modern browsers, and a package for other older browsers (more on that later), Because the browser I used supports ES6, and we know that the parent application of Qiankun introduced the child application, which essentially took HTML as the entry file and loaded the resource list (JS and CSS, etc.) required by the child application through the import-HTml-entry library, which should be due to the path problem. Error loading JS, plus nginx configured try_file to return HTML. Let me tell you a little bit about modern, Javascript Modules, and import-HTml-Entry
โ
1.1 modern pattern
โ
What Modern mode is, it is actually a build mode in the VUe-CLI command line tool, read more about vue CLI
โ
Modern mode builds applications in modern mode, delivers natively supported ES2015 code for modern browsers, and generates a package compatible with older browsers for automatic rollback.
In other words, in this mode Vue CLI builds two versions of JS packages: a native ES2015+ package that supports modern browsers, and a package that is compatible with other older browsers.
โ
๐จ๐ : Generate two sets of JS? What is the purpose of this
โ
Answer: We knew that newer features in ES2015 were not supported in older browsers, so we often had to convert them via Babel or add Polyfill to support older browsers, but as problems emerged, Babel converted code was often more verbose than the original ES2015 code. This leads to bigger files and less performance, but there are many browsers that are compatible with ES2015 +(also known as ES6). In both cases, the Vue CLI provides Modern mode to solve this problem, which is used to generate two SETS of JS systems, as shown below: an HTML entry based on the compiled mode ๐
We can clearly see the introduction of JS in the following two cases:
- Browsers that support native ES2015+ : JS will pass
<script type="module">
Loaded and ready to use<link rel="modulepreload">
Preload. - Unsupported browsers: JS will be used
<script nomodule>
While ignoring the loading of the js file defined as Module
In other words: Browsers that support mode. HTML generated in this mode passes through
โ
๐จ๐ Ah Feng: Shu Jiang jun, there is a js code in the middle of the screenshot, what is it?
โ
The answer: Scripts with the nomodule attribute are ignored by browsers that recognize the type=module syntax. Safari 10.1 is different. It does not support the nomodule property. It downloads the JS file of the Nomodule, but does not execute it. This code fixes this problem.
๐ฒ development:
- 10 nomodule on safari
1.2 JavaScript modules
โ
In the previous section, we introduced js files generated in vue-CLI Module mode. One of the build publications is the native ES2015+ package that supports modern browsers. Essentially, it relies on type= Module to load the ES Module. Let’s take a closer look at how compatible this property is across browsers
โ
When it comes to modules, I’m sure you’ll see keywords like export and import, as well as the scope of the module itself. It doesn’t pollute global variables, only in the module, and the use of these features also requires you to tell the javascript runtime whether the script being run is a normal script or a JS module
To do this, use the
โ
๐ฉ๐ Ah Qi: What is the difference between ordinary scripts and JS modules?
โ
Answer: The difference is as follows ๐ :
- Importing the same file multiple times,
JS module
It is executed only once, whereas normal scripts are executed and parsed multiple times, depending on how many times they are introduced - Cross-domain restrictions:
JS module
Need support in the request headerAccess-Control-Allow-Origin: *
Common scripts are not required - Order of execution:
JS module
The script will have one by defaultdefer
Property to delay the execution of the script. Normal JS scripts block HTML parsing by default
Of course you can also use to let the browser preload and precompile modules: modules and their dependencies
Let’s compare the image below. The same file, if directly usedModule
Introduce, relative to the size and volume of the document translated by Babel
โ
๐จ๐ Ah Le: I see that some referenced module files are named with the suffix MJS instead of JS?
โ
Answer: To better distinguish between imported files that are modules and files that are regular Javascript, and to ensure that your modules can be recognized by the runtime environment or build tools such as Babel and Babel.
โฐ If you are using MJS, you need to configure the MIME type on the server. Otherwise, an error will be reported. The server obligatory with a non-javascript MIME type of “”. Strict MIME type checking is ๆฎ ็พ for module scripts per HTML spec.
๐ฒ
- Deploying ES2015+ Code in Production Today
- JavaScript modules modules – JavaScript | MDN
- Efficient use of JavaScript Modules in the browser
1.3 the import – HTML – entry
โ
In essence, in the Qiankun architecture, (single-SPA + Sandbox + import-html-entry), HTML was used as the entry, which was to load the resources in THE HTML of the sub-application through import-html-entry. Then go to the export document link from the entry script to see how to use the library
โ
Let’s look at the implementation of the importHTML method
The importHTML(URL, opts = {}) method passes in two arguments
url
: Path to the HTML template to be parsedopts
: Includes the following attributes: Fetch (for obtaining remote script and style file content, browser-supported request library), getPublicPath (for obtaining static resource publicPath, converting external resources from relative paths to absolute paths in templates), getTemplate (for preprocessing before template parsing)
It also involves loading related functions to JS, CSS and other resources, and links are also used in Qiankun
getExternalStyleSheets
: used to distinguish whether CSS is inlined or inlined (style or link). If it is link, fetch the resource, and then extract the content to form an arraygetExternalScripts
: Gets all the script tags that appear in the template, extracts the contents, and forms an arrayexecScripts
: Executes all the code in script (via eval) and returns the module export object pointed to by the HTML template entry script link entry
โ
๐จ๐ Ahbin: How does import-HTml-entry extract different resources?
โ
Import-html-entry uses regular expressions to extract style, link, and script tags. The processTpl method is the core function for parsing templates in the process-tpl.js document link file. Here are some of the re’s
๐ฒ sauce previous articles:
- Construction of front-end Knowledge System of Tree Jam (PART 1)
- Construction of front-end Knowledge System of Tree Jam (Part 2)
- Talk about daily collaboration tools for front-end development
- Babel configuration is stupid
- How to better manage the Api
- The interviewer asks you about Node
- Front-end engineering stuff
- Did you learn BFF and Serverless
- Front-end operations and deployment
Please drink a cup ๐ต remember three even oh ~
1. Remember to give ๐ฒ sauce a thumbs up after reading oh, there is ๐ motivation
2. Pay attention to the interesting things at the front of the public account, and chat with you about the interesting things at the front
3. Github frontendThings thanks to Starโจ