Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产精品欧美在线,成年女人视频网站免费m,亚洲小说另类

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          (1)響應(yīng)式內(nèi)頁布局分析HTML模塊化和CSS模塊化詳解

          頁設(shè)計(jì)圖

          視頻講解課程

          1.設(shè)計(jì)圖分析和HTML模塊化結(jié)構(gòu):https://www.ixigua.com/i6903745684596326915/

          2.HTML模塊化和CSS模塊化示例:https://www.ixigua.com/i6904203127541465611/


          HTML+CSS模塊化基礎(chǔ)代碼

          核心知識(shí)點(diǎn)

          1. 分析設(shè)計(jì)圖結(jié)構(gòu)和模塊劃分
            1. 橫向分:頭部,導(dǎo)航,banner,中間主體,底部
            2. 按頁面分:列表頁,詳情頁,單頁
            3. 模塊劃分:列表,輪播,自定義模塊
          2. 了解頁面布局和模塊化布局的區(qū)別
            1. 頁面布局主要是分欄唯一功能,不能定義樣式,一般用 col-為前綴命名
          3. 了解html模塊化命名規(guī)范
            1. 列表類模塊使用 ul-為前綴命名
              1. 列表li里面的命名規(guī)范
                1. 都以短的英文縮寫為主
                2. 圖片 .pic
                3. 文本 .txt
                4. 標(biāo)題 .tit
                5. 日期 .date
                6. 簡介 .desc
                7. 信息 .info
                8. 按鈕 .btn
                9. 更多 .more
            2. 其他自定義模塊都用 m- 為前綴命名
            3. 單獨(dú)元素都已 g- 為前綴命名
              1. 大標(biāo)題 g-tit1
              2. 按鈕 g-btn
            4. 通用的模塊統(tǒng)一命名
              1. 頭部 header
              2. 底部 footer
              3. 主導(dǎo)航 nav
              4. 側(cè)導(dǎo)航 snv
              5. 分頁 pages
              6. 當(dāng)前位置 cur
          4. 了解CSS模塊化寫法規(guī)范和編碼順序
            1. 先寫初始化樣式
            2. 然后是頭部底部公用樣式
            3. 然后寫每個(gè)模塊的樣式
            4. 每個(gè)模塊的樣式都以模塊命開頭,每個(gè)模塊獨(dú)立
            5. .wp是限制頁面寬度的
            6. .col- 是頁面布局分欄的

          隨著 Web 技術(shù)的蓬勃發(fā)展和依賴的基礎(chǔ)設(shè)施日益完善,前端領(lǐng)域逐漸從瀏覽器擴(kuò)展至服務(wù)端(Node.js),桌面端(PC、Android、iOS),乃至于物聯(lián)網(wǎng)設(shè)備(IoT),其中 JavaScript 承載著這些應(yīng)用程序的核心部分,隨著其規(guī)模化和復(fù)雜度的成倍增長,其軟件工程體系也隨之建立起來(協(xié)同開發(fā)、單元測試、需求和缺陷管理等),模塊化編程的需求日益迫切。

          JavaScript 對(duì)模塊化編程的支持尚未形成規(guī)范,難以堪此重任;一時(shí)間,江湖俠士挺身而出,一路披荊斬棘,從刀耕火種過渡到面向未來的模塊化方案;

          更多關(guān)于我的文章和項(xiàng)目,歡迎關(guān)注 @x-cold

          概念

          模塊化編程就是通過組合一些__相對(duì)獨(dú)立可復(fù)用的模塊__來進(jìn)行功能的實(shí)現(xiàn),其最核心的兩部分是__定義模塊__和__引入模塊__;

          • 定義模塊時(shí),每個(gè)模塊內(nèi)部的執(zhí)行邏輯是不被外部感知的,只是導(dǎo)出(暴露)出部分方法和數(shù)據(jù);
          • 引入模塊時(shí),同步 / 異步去加載待引入的代碼,執(zhí)行并獲取到其暴露的方法和數(shù)據(jù);

          刀耕火種

          盡管 JavaScript 語言層面并未提供模塊化的解決方案,但利用其可__面向?qū)ο骭_的語言特性,外加__設(shè)計(jì)模式__加持,能夠?qū)崿F(xiàn)一些簡單的模塊化的架構(gòu);經(jīng)典的一個(gè)案例是利用單例模式模式去實(shí)現(xiàn)模塊化,可以對(duì)模塊進(jìn)行較好的封裝,只暴露部分信息給需要使用模塊的地方;

          // Define a module
          var moduleA = (function ($, doc) {
           var methodA = function() {};
           var dataA = {};
           return {
           methodA: methodA,
           dataA: dataA
           };
          })(jQuery, document);
          // Use a module
          var result = moduleA.mehodA();
          

          直觀來看,通過立即執(zhí)行函數(shù)(IIFE)來聲明依賴以及導(dǎo)出數(shù)據(jù),這與當(dāng)下的模塊化方案并無巨大的差異,可本質(zhì)上卻有千差萬別,無法滿足的一些重要的特性;

          • 定義模塊時(shí),聲明的依賴不是強(qiáng)制自動(dòng)引入的,即在定義該模塊之前,必須手動(dòng)引入依賴的模塊代碼;
          • 定義模塊時(shí),其代碼就已經(jīng)完成執(zhí)行過程,無法實(shí)現(xiàn)按需加載;
          • 跨文件使用模塊時(shí),需要將模塊掛載到全局變量(window)上;

          AMD & CMD 二分天下

          題外話:由于年代久遠(yuǎn),這兩種模塊化方案逐漸淡出歷史舞臺(tái),具體特性不再細(xì)聊;

          為了解決”刀耕火種”時(shí)代存留的需求,AMD 和 CMD 模塊化規(guī)范問世,解決了在瀏覽器端的異步模塊化編程的需求,__其最核心的原理是通過動(dòng)態(tài)加載 script 和事件監(jiān)聽的方式來異步加載模塊;__

          AMD 和 CMD 最具代表的兩個(gè)作品分別對(duì)應(yīng) require.js 和 sea.js;其主要區(qū)別在于依賴聲明和依賴加載的時(shí)機(jī),其中 require.js 默認(rèn)在聲明時(shí)執(zhí)行, sea.js 推崇懶加載和按需使用;另外值得一提的是,CMD 規(guī)范的寫法和 CommonJS 極為相近,只需稍作修改,就能在 CommonJS 中使用。參考下面的 Case 更有助于理解;

          // AMD
          define(['./a','./b'], function (moduleA, moduleB) {
           // 依賴前置
           moduleA.mehodA();
           console.log(moduleB.dataB);
           // 導(dǎo)出數(shù)據(jù)
           return {};
          });
           
          // CMD
          define(function (requie, exports, module) {
           // 依賴就近
           var moduleA = require('./a');
           moduleA.mehodA(); 
           // 按需加載
           if (needModuleB) {
           var moduleB = requie('./b');
           moduleB.methodB();
           }
           // 導(dǎo)出數(shù)據(jù)
           exports = {};
          });
          

          CommonJS

          2009 年 ry 發(fā)布 Node.js 的第一個(gè)版本,CommonJS 作為其中最核心的特性之一,適用于服務(wù)端下的場景;歷年來的考察和時(shí)間的洗禮,以及前端工程化對(duì)其的充分支持,CommonJS 被廣泛運(yùn)用于 Node.js 和瀏覽器;

          // Core Module
          const cp = require('child_process');
          // Npm Module
          const axios = require('axios');
          // Custom Module
          const foo = require('./foo');
          module.exports = { axios };
          exports.foo = foo;
          

          規(guī)范

          • module (Object): 模塊本身
          • exports (*): 模塊的導(dǎo)出部分,即暴露出來的內(nèi)容
          • require (Function): 加載模塊的函數(shù),獲得目標(biāo)模塊的導(dǎo)出值(基礎(chǔ)類型為復(fù)制,引用類型為淺拷貝),可以加載內(nèi)置模塊、npm 模塊和自定義模塊

          實(shí)現(xiàn)

          1、模塊定義

          默認(rèn)任意 .node .js .json 文件都是符合規(guī)范的模塊;

          2、引入模塊

          首先從緩存(require.cache)優(yōu)先讀取模塊,如果未命中緩存,則進(jìn)行路徑分析,然后按照不同類型的模塊處理:

          • 內(nèi)置模塊,直接從內(nèi)存加載;
          • 外部模塊,首先進(jìn)行文件尋址定位,然后進(jìn)行編譯和執(zhí)行,最終得到對(duì)應(yīng)的導(dǎo)出值;

          其中在編譯的過程中,Node對(duì)獲取的JavaScript文件內(nèi)容進(jìn)行了頭尾包裝,結(jié)果如下:

          (function (exports, require, module, __filename, __dirname) {
           var circle = require('./circle.js');
           console.log('The area of a circle of radius 4 is ' + circle.area(4));
          });
          

          特性總結(jié)

          • 同步執(zhí)行模塊聲明和引入邏輯,分析一些復(fù)雜的依賴引用(如循環(huán)依賴)時(shí)需注意;
          • 緩存機(jī)制,性能更優(yōu),同時(shí)限制了內(nèi)存占用;
          • Module 模塊可供改造的靈活度高,可以實(shí)現(xiàn)一些定制需求(如熱更新、任意文件類型模塊支持);

          ES Module(推薦使用)

          ES Module 是語言層面的模塊化方案,由 ES 2015 提出,其規(guī)范與 CommonJS 比之 ,導(dǎo)出的值都可以看成是一個(gè)具備多個(gè)屬性或者方法的對(duì)象,可以實(shí)現(xiàn)互相兼容;但寫法上 ES Module 更簡潔,與 Python 接近;

          import fs from 'fs';
          import color from 'color';
          import service, { getArticles } from '../service'; 
          export default service;
          export const getArticles = getArticles;
          

          主要差異在于:

          • ES Module 會(huì)對(duì)靜態(tài)代碼分析,即在代碼編譯時(shí)進(jìn)行模塊的加載,在運(yùn)行時(shí)之前就已經(jīng)確定了依賴關(guān)系(可解決循環(huán)引用的問題);
          • ES Module 關(guān)鍵字:import export 以及獨(dú)有的 default 關(guān)鍵字,確定默認(rèn)的導(dǎo)出值;
          • ES Module 中導(dǎo)出的值是一個(gè) 只讀的值的引用 ,無論基礎(chǔ)類型和復(fù)雜類型,而在 CommonJS 中 require 的是值的拷貝,其中復(fù)雜類型是值的淺拷貝;
          // a.js
          export let a = 1;
          export function caculate() {
           a++;
          };
          // b.js
          import { a, caculate } from 'a.js';
          console.log(a); // 1
          caculate();
          console.log(a); // 2
          a = 2; // Syntax Error: "a" is read-only
          

          UMD

          通過一層自執(zhí)行函數(shù)來兼容各種模塊化規(guī)范的寫法,兼容 AMD / CMD / CommonJS 等模塊化規(guī)范,貼上代碼勝過千言萬語,需要特別注意的是 ES Module 由于會(huì)對(duì)靜態(tài)代碼進(jìn)行分析,故這種運(yùn)行時(shí)的方案無法使用,此時(shí)通過 CommonJS 進(jìn)行兼容;

          (function (global, factory) {
           if (typeof exports === 'object') { 
           module.exports = factory();
           } else if (typeof define === 'function' && define.amd) {
           define(factory);
           } else {
           this.eventUtil = factory();
           }
          })(this, function (exports) {
           ? // Define Module
           Object.defineProperty(exports, "__esModule", {
           value: true
           });
           exports.default = 42;
          });
          

          構(gòu)建工具中的實(shí)現(xiàn)

          為了在瀏覽器環(huán)境中運(yùn)行模塊化的代碼,需要借助一些模塊化打包的工具進(jìn)行打包( 以 webpack 為例),定義了項(xiàng)目入口之后,會(huì)先快速地進(jìn)行依賴的分析,然后將所有依賴的模塊轉(zhuǎn)換成瀏覽器兼容的對(duì)應(yīng)模塊化規(guī)范的實(shí)現(xiàn);

          模塊化的基礎(chǔ)

          從上面的介紹中,我們已經(jīng)對(duì)其規(guī)范和實(shí)現(xiàn)有了一定的了解;在瀏覽器中,要實(shí)現(xiàn) CommonJS 規(guī)范,只需要實(shí)現(xiàn) module / exports / require / global 這幾個(gè)屬性,由于瀏覽器中是無法訪問文件系統(tǒng)的,因此 require 過程中的文件定位需要改造為加載對(duì)應(yīng)的 JS 片段(webpack 采用的方式為通過函數(shù)傳參實(shí)現(xiàn)依賴的引入)。具體實(shí)現(xiàn)可以參考:tiny-browser-require。

          webpack 打包出來的代碼快照如下,注意看注釋中的時(shí)序;

          (function (modules) {
           // The module cache
           var installedModules = {};
           // The require function
           function __webpack_require__(moduleId) {}
           return __webpack_require__(0); // ---> 0
          })
          ({
           0: function (module, exports, __webpack_require__) {
           // Define module A
           var moduleB = __webpack_require__(1); // ---> 1
           },
           1: function (module, exports, __webpack_require__) {
           // Define module B
           exports = {}; // ---> 2
           }
          });
          

          實(shí)際上,ES Module 的處理同 CommonJS 相差無幾,只是在定義模塊和引入模塊時(shí)會(huì)去處理 __esModule 標(biāo)識(shí),從而兼容其在語法上的差異。

          異步和擴(kuò)展

          1、瀏覽器環(huán)境下,網(wǎng)絡(luò)資源受到較大的限制,因此打包出來的文件如果體積巨大,對(duì)頁面性能的損耗極大,因此需要對(duì)構(gòu)建的目標(biāo)文件進(jìn)行拆分,同時(shí)模塊也需要支持動(dòng)態(tài)加載;

          webpack 提供了兩個(gè)方法 require.ensure() 和 import() (推薦使用)進(jìn)行模塊的動(dòng)態(tài)加載,至于其中的原理,跟上面提及的 AMD & CMD 所見略同,import() 執(zhí)行后返回一個(gè) Promise 對(duì)象,其中所做的工作無非也是動(dòng)態(tài)新增 script 標(biāo)簽,然后通過 onload / onerror 事件進(jìn)一步處理。

          2、由于 require 函數(shù)是完全自定義的,我們可以在模塊化中實(shí)現(xiàn)更多的特性,比如通過修改 require.resolve 或 Module._extensions 擴(kuò)展支持的文件類型,使得 css / .jsx / .vue / 圖片等文件也能為模塊化所使用;

          附錄1:特性一覽表

          附錄2:參考

          • AMD 模塊化規(guī)范: https://github.com/amdjs/amdjs-api/wiki/AMD
          • CMD 模塊定義規(guī)范:https://github.com/seajs/seajs/issues/242
          • webpack 模塊相關(guān)文檔: https://webpack.js.org/concepts/modules/
          • 瀏覽器加載 CommonJS 模塊的原理與實(shí)現(xiàn):http://www.ruanyifeng.com/blog/2015/05/commonjs-in-browser.html

          作者:x-cold

          本文主要理理js模塊化相關(guān)知識(shí)。
          涉及到內(nèi)聯(lián)腳本、外聯(lián)腳本、動(dòng)態(tài)腳本、阻塞、
          deferasyncCommonJSAMDCMDUMDES Module。順帶探究下Vite

          內(nèi)聯(lián)腳本

          假設(shè)你是一個(gè)前端新手,現(xiàn)在入門,那么我們創(chuàng)建一個(gè)html頁面,需要新建一個(gè)index.html文件:

          <!DOCTYPE html>
          <html>
          <head>
            <title>test</title>
          </head>
          <body>
            <p id="content">hello world</p>
          </body>
          </html>

          如果需要在頁面中執(zhí)行javascript代碼,我們就需要在 HTML 頁面中插入 <script> 標(biāo)簽。

          有2種插入方式:
          1、放在
          <head>
          2、放在<body>

          比如,點(diǎn)擊hello world之后,在hello world后面加3個(gè)感嘆號(hào)的功能,我們在head中加入script標(biāo)簽,并給hello world綁定點(diǎn)擊事件:

          <!DOCTYPE html>
          <html>
          <head>
            <title>test</title>
            <script>
              function myFunction() {
                document.getElementById('content').innerHTML = 'hello world!!!'
              }
            </script>
          </head>
          
          <body>
            <p id="content" onclick="myFunction()">hello world</p>
          </body>
          </html>

          如果加在body中,一般放在body的最后面:

          <!DOCTYPE html>
          <html>
          <head>
            <title>test</title>
          </head>
          
          <body>
            <p id="content" onclick="myFunction()">hello world</p>
            <script>
              function myFunction() {
                document.getElementById('content').innerHTML = 'hello world!!!'
              }
            </script>
          </body>
          </html>

          簡單的邏輯我們可以用這2種方式寫,這種方式叫做內(nèi)聯(lián)腳本。

          外聯(lián)腳本

          當(dāng)邏輯復(fù)雜時(shí),我們可以把上面的script標(biāo)簽中的代碼抽取出來,比如在html的同級(jí)目錄創(chuàng)建一個(gè)js文件夾,里面新建一個(gè)a.js的文件。

          a.js中寫上面script標(biāo)簽中的代碼:

          function myFunction() {
            document.getElementById('content').innerHTML = 'hello world!!!'
          }

          上面的script標(biāo)簽則可以改成:

          <script src="./js/a.js"></script>

          阻塞

          上面的2種寫法,瀏覽器在加載html時(shí),遇到script標(biāo)簽,會(huì)停止解析html。
          內(nèi)聯(lián)腳本會(huì)立刻執(zhí)行;外聯(lián)腳本會(huì)先下載再立刻執(zhí)行。
          等腳本執(zhí)行完畢才會(huì)繼續(xù)解析html。
          (html解析到哪里,頁面就能顯示到哪里,用戶也能看到哪里)

          比如下面的代碼:

          <p>...content before script...</p>
          
          <script src="./js/a.js"></script>
          
          <p>...content after script...</p>

          解析到第一個(gè)p標(biāo)簽,我們能看到...content before script...顯示在了頁面中,然后瀏覽器遇到script標(biāo)簽,會(huì)停止解析html,而去下載a.js并執(zhí)行,執(zhí)行完a.js才會(huì)繼續(xù)解析html,然后頁面中才會(huì)出現(xiàn)...content after script...

          我們可以通過Chrome的Developer Tools分析一下index.html加載的時(shí)間線:

          這會(huì)導(dǎo)致2個(gè)問題:
          1、腳本無法訪問它下面的dom;
          2、如果頁面頂部有個(gè)笨重的腳本,在它執(zhí)行完之前,用戶都看不到完整的頁面。

          對(duì)于問題2,我們可以把腳本放在頁面底部,這樣它可以訪問到上面的dom,且不會(huì)阻塞頁面的顯示:

          <body>
            ...all content is above the script...
          
            <script src="./js/a.js"></script>
          </body>

          但這不是最好的辦法,我們接著往下看。

          defer

          我們給script標(biāo)簽加defer屬性,就像下面這樣:

          <p>...content before script...</p>
          
          <script defer src="./js/a.js"></script>
          
          <p>...content after script...</p>

          defer 特性告訴瀏覽器不要等待腳本。于是,瀏覽器將繼續(xù)解析html,腳本會(huì)并行下載,然后等 DOM 構(gòu)建完成后,腳本才會(huì)執(zhí)行。

          這樣script標(biāo)簽不再阻塞html的解析。

          這時(shí)再看時(shí)間線:

          需要注意的是,具有 defer 特性的腳本保持其相對(duì)順序。

          比如:

          <script defer src="./js/a.js"></script>
          <script defer src="./js/b.js"></script>

          上面的2個(gè)腳本會(huì)并行下載,但是不論哪個(gè)先下載完成,都是先執(zhí)行a.js,a.js執(zhí)行完才會(huì)執(zhí)行b.js。
          這時(shí),如果b.js依賴a.js,這種寫法將很有用。

          另外需要注意的是,defer 特性僅適用于外聯(lián)腳本,即如果 script標(biāo)簽沒有 src屬性,則會(huì)忽略 defer 特性。

          async

          我們可以給script標(biāo)簽加async屬性,就像下面這樣:

          <script async src="./js/a.js"></script>

          這會(huì)告訴瀏覽器,該腳本完全獨(dú)立。
          獨(dú)立的意思是,DOM 和其他腳本不會(huì)等待它,它也不會(huì)等待其它東西。async 腳本就是一個(gè)會(huì)在加載完成時(shí)立即執(zhí)行的完全獨(dú)立的腳本。

          這時(shí)再看時(shí)間線:

          可以看到,雖然下載a.js不阻塞html的解析,但是執(zhí)行a.js會(huì)阻塞。

          還需要注意多個(gè)async時(shí)的執(zhí)行順序,比如下面這段代碼:

          <p>...content before script...</p>
          
          <script async src="./js/a.js"></script>
          <script async src="./js/b.js"></script>
          
          <p>...content after script...</p>

          兩個(gè)p標(biāo)簽的內(nèi)容會(huì)立刻顯示出來,a.js和b.js則并行下載,且下載成功后立刻執(zhí)行,所以多個(gè)async時(shí)的執(zhí)行順序是誰先下載成功誰先執(zhí)行。
          一些比較獨(dú)立的腳本,比如性能監(jiān)控,就很適合用這種方式加載。

          另外,和defer一樣,async 特性也僅適用于外聯(lián)腳本。

          動(dòng)態(tài)腳本

          我們可以動(dòng)態(tài)地創(chuàng)建一個(gè)script標(biāo)簽并append到文檔中。

          let script = document.createElement('script')
          script.src = '/js/a.js'
          document.body.append(script)

          append后腳本就會(huì)立刻開始加載,表現(xiàn)默認(rèn)和加了async屬性一致。
          我們可以顯示的設(shè)置
          script.async = false來改變這個(gè)默認(rèn)行為,那么這時(shí)表現(xiàn)就和加了defer屬性一致。

          上面的這些寫法,當(dāng)script標(biāo)簽變多時(shí),容易導(dǎo)致全局作用域污染,還要維護(hù)書寫順序,要解決這個(gè)問題,需要一種將 JavaScript 程序拆分為可按需導(dǎo)入的單獨(dú)模塊的機(jī)制,即js模塊化,我們接著往下看。

          CommonJS

          很長一段時(shí)間 JavaScript 沒有模塊化的概念,直到 Node.js 的誕生,把 JavaScript 帶到服務(wù)端,這時(shí),CommonJS誕生了。

          CommonJS定義了三個(gè)全局變量:

          require,exports,module

          require 讀入并執(zhí)行一個(gè) js 文件,然后返回其 exports 對(duì)象;
          exports 對(duì)外暴露模塊的接口,可以是任何類型,指向 module.exports;
          module 是當(dāng)前模塊,exports 是 module 上的一個(gè)屬性。

          Node.js 使用了CommonJS規(guī)范。

          比如:

          // a.js
          let name = 'Lily'
          export.name = name
          
          // b.js
          let a = require('a.js')
          console.log(a.name) // Lily

          由于CommonJS不適合瀏覽器端,于是出現(xiàn)了AMD和CMD規(guī)范。

          AMD

          AMD(Asynchronous Module Definition) 是 RequireJS 在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出。

          基本思想是,通過 define 方法,將代碼定義為模塊。當(dāng)這個(gè)模塊被 require 時(shí),開始加載依賴的模塊,當(dāng)所有依賴的模塊加載完成后,開始執(zhí)行回調(diào)函數(shù),返回該模塊導(dǎo)出的值。

          使用時(shí),需要先引入require.js:

          <script src="require.js"></script>
          <script src="a.js"></script>

          然后可以這樣寫:

          // a.js
          define(function() {
              let name = 'Lily'
              return {
                  name
              }
          })
          // b.js
          define(['a.js'], function(a) {
              let name = 'Bob'
              console.log(a.name) // Lily
              return {
                  name
              }
          })

          CMD

          CMD(Common Module Definition) 是 Sea.js 在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出。

          使用時(shí),需要先引入sea.js:

          <script src="sea.js"></script>
          <script src="a.js"></script>

          然后可以這樣寫:

          // a.js
          define(function(require, exports, module) {
              var name = 'Lily'
              exports.name = name
          })
          
          // b.js
          define(function(require, exports, module) {
              var name = 'Bob'
              var a = require('a.js')
              console.log(a.name) // 'Lily'
              exports.name = name
          })

          UMD

          UMD (Universal Module Definition) 目的是提供一個(gè)前后端跨平臺(tái)的解決方案(兼容全局變量、AMD、CMD和CommonJS)。

          實(shí)現(xiàn)很簡單,判斷不同的環(huán)境,然后以不同的方式導(dǎo)出模塊:

          (function (root, factory) {
              if (typeof define === 'function' && (define.amd || define.cmd)) {
                  // AMD、CMD
                  define([], factory);
              } else if (typeof module !== 'undefined' && typeof exports === 'object') {
                  // Node、CommonJS
                  module.exports = factory();
              } else {
                  // 瀏覽器全局變量
                  root.moduleName = factory();
            }
          }(this, function () {
              // 只需要返回一個(gè)值作為模塊的export
              // 這里我們返回了一個(gè)空對(duì)象
              // 你也可以返回一個(gè)函數(shù)
              return {};
          }));

          ES Module

          AMD 和 CMD 是社區(qū)的開發(fā)者們制定的模塊加載方案,并不是語言層面的標(biāo)準(zhǔn)。從 ES6 開始,在語言標(biāo)準(zhǔn)的層面上,實(shí)現(xiàn)了模塊化功能,而且實(shí)現(xiàn)得相當(dāng)簡單,完全可以取代上文的規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。

          ES6 的模塊自動(dòng)采用嚴(yán)格模式。模塊功能主要由兩個(gè)命令構(gòu)成:export和import。

          export命令用于規(guī)定模塊的對(duì)外接口;
          import命令用于輸入其他模塊提供的功能。

          比如上面的代碼,我們可以這樣寫:

          // a.js
          const name = 'Lily'
          
          export {
            name
          }
          
          // 等價(jià)于
          export const name = 'Lily'
          
          // b.js
          import { name } from 'a.js'
          console.log(name) // Lily
          
          // b.js
          import * as a from 'a.js'
          console.log(a.name) // Lily

          此外,還可以用export default默認(rèn)導(dǎo)出的寫法:

          // a.js
          const name = 'Lily'
          
          export default {
            name
          }
          
          // b.js
          import a from 'a.js'
          console.log(a.name) // Lily

          如果只想運(yùn)行a.js,可以只import:

          // b.js
          import 'a.js'

          我們可以給script標(biāo)簽加type=module讓瀏覽器以 ES Module 的方式加載腳本:

          <script type="module" src="./js/b.js"></script>

          這時(shí),script標(biāo)簽會(huì)默認(rèn)有defer屬性(也可以設(shè)置成async),支持內(nèi)聯(lián)和外聯(lián)腳本。

          這時(shí)我們運(yùn)行打開index.html,會(huì)發(fā)現(xiàn)瀏覽器報(bào)錯(cuò)了:

          這是因?yàn)?type=module 的 script 標(biāo)簽加強(qiáng)了安全策略,瀏覽器加載不同域的腳本資源時(shí),如果服務(wù)器未返回有效的 Allow-Origin 相關(guān) CORS 頭,會(huì)禁止加載改腳本。而這里啟動(dòng)的index.html是一個(gè)本地文件(地址是file://路徑),將會(huì)遇到 CORS 錯(cuò)誤,需要通過一個(gè)服務(wù)器來啟動(dòng) HTML 文件。

          Vite

          在瀏覽器支持 ES Module 之前,我們用工具實(shí)現(xiàn)JavaScript模塊化的開發(fā),比如webpack、Rollup 和 Parcel 。但是當(dāng)項(xiàng)目越來越大后,本地?zé)岣略絹碓铰?Vite 旨在利用ESM解決上述問題。

          Vite使用簡單,可以去官網(wǎng)(https://cn.vitejs.dev/)看看。

          總結(jié)

          老的規(guī)范了解即可,未來是ES Module的,用Vite可以極大的提升開發(fā)時(shí)的體驗(yàn),生產(chǎn)環(huán)境用Rollup打包。


          主站蜘蛛池模板: 日韩免费一区二区三区在线| 国产未成女一区二区三区| 日本一区二区不卡视频| 在线|一区二区三区四区| 国产福利电影一区二区三区,亚洲国模精品一区 | 精品成人一区二区三区免费视频 | 国产福利电影一区二区三区,亚洲国模精品一区 | 视频一区二区三区免费观看| 波多野结衣一区二区| 亚洲视频在线一区| 国产激情无码一区二区| 手机看片一区二区| 中文字幕AV一区中文字幕天堂| 四虎一区二区成人免费影院网址| 怡红院AV一区二区三区| 久久精品无码一区二区三区免费| 久久伊人精品一区二区三区| 久久一区二区明星换脸| 日韩在线不卡免费视频一区| 精品视频一区二区三区在线观看| 三上悠亚日韩精品一区在线 | 国产精品无码一区二区三区不卡| 精品三级AV无码一区| 精品无码一区二区三区爱欲九九| 无码视频一区二区三区在线观看 | 亚洲一区二区久久| 97精品国产一区二区三区| 中文字幕一区二区三区久久网站| 亚洲国产精品一区二区久久hs| 亚洲AV无码一区二区三区系列| 少妇激情一区二区三区视频| 精品无码av一区二区三区| 在线视频一区二区| 中文乱码人妻系列一区二区| 精品少妇人妻AV一区二区| 综合激情区视频一区视频二区| 影院无码人妻精品一区二区| 亚洲永久无码3D动漫一区| 亚洲国产一区在线观看| 亚洲精品日韩一区二区小说| 夜精品a一区二区三区|