Working principle:
A picture explains the principle of Vite: What does the browser do?Host file index.html<script type="module" src="/src/main.js"></script> After the browser obtains the resources in the host file, it finds that it needs to request the main.js file again. A resource request for main.js will be sent to the server again. main.jsIn main, it can be found that the browser once again initiates resource requests for the two files vue.js?v=d253a66c and App.vue?t=1637479953836. The server compiles the content in App.vue and returns it to the browser. As shown in the figure below, the logo image and text are compiled into a static node of _hoisted_. From the request header, we can also see that the sfc file has become a js file that can be recognized by the browser (the app.vue file must have script content to be compiled into js). For the browser, what is executed is a piece of js code. Other bare modulesIf there are other dependencies in the vue dependency, the browser will still initiate a resource request again to obtain the corresponding resources. Learn about pre-packagingFor the loading of third-party dependencies (bare modules), vite packages them in advance and puts them under node_modules/.vite. When starting the project, download the file directly from this path. From the above figure, we can see that the path changes when the bare module is introduced. What does the server do?To sum up: the server processes the files with special suffixes and returns them to the front end for display. We can simulate vite's devServe and start a local service using koa middleware. //Introduce dependencies const Koa = require('koa') const app = new Koa() const fs = require('fs') const path = require('path') const compilerSfc = require('@vue/compiler-sfc') const compilerDom = require('@vue/compiler-dom') app.use(async (ctx) => { const { url, query } = ctx.request //Write all the code for processing request resources here}) app.listen(3001, () => { console.log('dyVite start!!') }) Request home page index.htmlif (url === '/') { const p = path.join(__dirname, './index.html') // absolute path // Home page ctx.type = 'text/html' ctx.body = fs.readFileSync(p, 'utf8') } Looking at the picture above, you know that our host file has been requested successfully. It's just that the browser sends another request for the main.js file to the server. At this time, we also need to judge and process the main.js file. Request files ending with .jsAfter we deal with the above situation, emmmm. . . It was found that there were still many other resource requests in main. Basic js filemain file: console.log(1) Processing main: else if (url.endsWith('.js')) { // Respond to js request const p = path.join(__dirname, url) ctx.type = 'text/javascript' ctx.body = rewriteImport(fs.readFileSync(p, 'utf8')) // Processing dependent functions} Handle the dependencies in mainDo you think there is only one output in main? Too naive. Can this be handled? main file: import { createApp, h } from 'vue' createApp({ render: () => h('div', 'helllo dyVite!') }).mount('#app') emmm. . . It should be possible! We can turn the address imported in main into a relative address. Add /@modules/ to the bare module path. Then identify the files in /@modules/ (bare module files). // Convert the readable file address into a relative address // Regular replacement rewrites the import into a relative address // import { createApp } from 'vue' => import { createApp } from '/@modules/vue' function rewriteImport(content) { return content.replace(/ from ['|"](.*)['|"]/g, function (s0, s1) { // s0 matches the string, s1 groups the content // Is it a relative path if (s1.startsWith('./') || s1.startsWith('/') || s1.startsWith('../')) { // Return directly to return s0 } else { return `from '/@modules/${s1}'` } }) } For third-party dependencies, vite uses pre-packaged requests to request internal resources under its own server/node_modules/.vite/. We can simplify it a bit and get the corresponding resources from node_modules on the client using the dependency name. else if (url.startsWith('/@modules/')) { // Loading of bare modules const moduleName = url.replace('/@modules/', '') const pre's address const module = require(prefix + '/package.json').module const filePath = path.join(prefix, module) // Get the address of the file to be loaded // Read related dependencies const ret = fs.readFileSync(filePath, 'utf8') ctx.type = 'text/javascript' ctx.body = rewriteImport(ret) //There may be dependencies inside the dependency, so recursion is required} When rendering in main, the following error will be reported: The files we load are all libraries executed by the server. Code for the node environment may be generated inside, so we need to judge the environment variables. If you are developing, some warning messages will be output, but there will be no warning messages on the front end. So we need to mock it and tell the browser our current environment. Add process environment variables to html. <script> window.process = { env: { NODE_ENV: 'dev' } } </script> At this point the main file is loaded. But this is far from achieving our goal! What we need is a server that can compile vue files! Processing .vue filesmain.js file: import { createApp, h } from 'vue' import App from './App.vue' createApp(App).mount('#app') In the vue file, it is loaded modularly. When processing vue files, we need to process the parameters carried after .vue. Here, we simplify and only consider the template and sfc cases. else if (url.indexOf('.vue') > -1) { // Process vue file App.vue?vue&type=style&index=0&lang.css // Read vue content const p = path.join(__dirname, url.split('?')[0]) // compilerSfc parses sfc to obtain ast const ret = compilerSfc.parse(fs.readFileSync(p, 'utf8')) // App.vue?type=template // If the request does not have query.type, it means it is sfc if (!query.type) { // Process internal script const scriptContent = ret.descriptor.script.content // Convert the default export configuration object to a constant const script = scriptContent.replace( 'export default ', 'const __script = ', ) ctx.type = 'text/javascript' ctx.body = ` ${rewriteImport(script)} // Template parsing is converted to a separate request for a resource import {render as __render} from '${url}?type=template' __script.render = __render export default __script ` } else if (query.type === 'template') { const tpl = ret.descriptor.template.content // Compile including render module const render = compilerDom.compile(tpl, { mode: 'module' }).code ctx.type = 'text/javascript' ctx.body = rewriteImport(render) } } Processing image pathsRead directly from the client. else if (url.endsWith('.png')) { ctx.body = fs.readFileSync('src' + url) } SummarizeThis is the end of this article about what Vite does to browser requests. For more information about Vite browser requests, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: MySQL database Load Data multiple uses
Table of contents 1. Why is JavaScript single-thr...
We don’t often encounter 404 pages when we browse...
1. Introduction to compression and packaging Comm...
What is margin-top collapse Margin-top collapse i...
Table of contents Array deduplication 1. from() s...
Preface Recently, I have been busy dealing with s...
Table of contents Overview Single file components...
Prerequisites for installing MySQL: Install CentO...
There are many tasks to be done in search engine o...
1. Introduction I wrote an article before: The pr...
Table of contents 1. General steps for SQL optimi...
Preface BINARY and VARBINARY are somewhat similar...
First, we need to use the transform-origin attrib...
It is very simple to build a go environment under...
1. Concept 1. The difference between hot backup a...