摘要:規范則是非同步加載模塊,允許指定回調函數,可以實現異步加載依賴模塊,并且會提前加載由于主要用于服務器編程,模塊文件一般都已經存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以規范比較適用。
JS模塊化 模塊化的理解
什么是模塊?
將一個復雜的程序依據一定的規則(規范)封裝成幾個塊(文件), 并進行組合在一起;
塊的內部數據/實現是私有的, 只是向外部暴露一些接口(方法)與外部其它模塊通信;
一個模塊的組成
數據--->內部的屬性;
操作數據的行為--->內部的函數;
模塊化是指解決一個復雜的問題時自頂向下把系統劃分成若干模塊的過程,有多種屬性,分別反映其內部特性;
模塊化編碼:編碼時是按照模塊一個一個編碼的, 整個項目就是一個模塊化的項目;
非模塊化的問題頁面加載多個js的問題:
發生問題:
難以維護 ;
依賴模糊;
請求過多;
所以,這些問題可以通過現代模塊化編碼和項目構建來解決;
模塊化的優點更好地分離:避免一個頁面中放置多個script標簽,而只需加載一個需要的整體模塊即可,這樣對于HTML和JavaScript分離很有好處;
更好的代碼組織方式:有利于后期更好的維護代碼;
按需加載:提高使用性能,和下載速度,按需求加載需要的模塊
避免命名沖突:JavaScript本身是沒有命名空間,經常會有命名沖突,模塊化就能使模塊內的任何形式的命名都不會再和其他模塊有沖突。
更好的依賴處理:使用模塊化,只需要在模塊內部申明好依賴的就行,增加刪除都直接修改模塊即可,在調用的時候也不用管該模塊依賴了哪些其他模塊。
模塊化的發展歷程 原始寫法只是把不同的函數簡單地放在一起,就算一個模塊;
function fun1(){ //... } function fun2(){ //... } //上面的函數fun1,fun2組成了一個模塊,使用的時候直接調用某個函數就行了。
缺點:
"污染"了全局變量,無法保證不與其他模塊發生變量名沖突;
模塊成員之間看不出直接關系。
對象寫法為了解決污染全局變量的問題,可以把模塊寫成一個對象,所有的模塊成員都放到這個對象里面。
var module1 = new Object({ count : 0, fun1 : function (){ //... }, fun2 : function (){ //... } }); //這個里面的fun1和fun2都封裝在一個賭俠寧里,可以通過對象.方法的形式進行調用; module1.fun1();
優點:
減少了全局上的變量數目;
缺點:
本質是對象,而這個對象會暴露所有模塊成員,內部狀態可以被外部改寫。
立即執行函數(IIFE模式)避免暴露私有成員,所以使用立即執行函數(自調函數,IIFE);
作用: 數據是私有的, 外部只能通過暴露的方法操作
var module1 = (function(){ var count = 0; var fun1 = function(){ //... } var fun2 = function(){ //... } //將想要暴露的內容放置到一個對象中,通過return返回到全局作用域。 return{ fun1:fun1, fun2:fun2 } })() //這樣的話只能在全局作用域中讀到fun1和fun2,但是讀不到變量count,也修改不了了。 //問題:當前這個模塊依賴另一個模塊怎么辦?IIFE的增強(引入依賴)
如果一個模塊很大,必須分成幾個部分,或者一個模塊需要繼承另一個模塊,這時就有必要采用"增強模式";
IIFE模式增強:引入依賴;
這就是現代模塊實現的基石;
var module1 = (function (mod){ mod.fun3 = function () { //... }; return mod; })(module1); //為module1模塊添加了一個新方法fun3(),然后返回新的module1模塊。 //引入jquery到項目中; var Module = (function($){ var _$body = $("body"); // we can use jQuery now! var foo = function(){ console.log(_$body); // 特權方法 } // Revelation Pattern return { foo: foo } })(jQuery) Module.foo();js模塊化需要解決那些問題:
1.如何安全的包裝一個模塊的代碼?(不污染模塊外的任何代碼)
2.如何唯一標識一個模塊?
3.如何優雅的把模塊的API暴漏出去?(不能增加全局變量)
4.如何方便的使用所依賴的模塊?
模塊化規范Node: 服務器端
Browserify : 瀏覽器端
CommonJS:服務器端
概述
Node 應用由模塊組成,采用 CommonJS 模塊規范。
CommonJS規范規定,每個模塊內部,module變量代表當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性。
特點
所有代碼都運行在模塊作用域,不會污染全局作用域。
模塊可以多次加載,但是只會在第一次加載時運行一次,然后運行結果就被緩存了,以后再加載,就直接讀取緩存結果。要想讓模塊再次運行,必須清除緩存。
模塊加載的順序,按照其在代碼中出現的順序。
基本語法:
定義暴露模塊 : exports
exports.xxx = value // 通過module.exports指定暴露的對象value module.exports = value
引入模塊 : require
var module = require("模塊相對路徑")
引入模塊發生在什么時候?
Node:運行時, 動態同步引入;
Browserify:在運行前對模塊進行編譯/轉譯/打包的處理(已經將依賴的模塊包含進來了), 運行的是打包生成的js, 運行時不需要再從遠程引入依賴模塊;
CommonJS通用的模塊規范(同步)Node內部提供一個Module構建函數。所有模塊都是Module的實例。
每個模塊內部,都有一個module對象,代表當前模塊。
module.exports屬性表示當前模塊對外輸出的接口,其他文件加載該模塊,實際上就是讀取module.exports變量。
Node為每個模塊提供一個exports變量,指向module.exports。
如果一個模塊的對外接口,就是一個單一的值,不能使用exports輸出,只能使用module.exports輸出。
Modules/1.0規范包含內容:
模塊的標識應遵循的規則(書寫規范)
定義全局函數require,通過傳入模塊標識來引入其他模塊,執行的結果即為模塊暴露出來的API;
如果被require函數引入的模塊中也包含依賴,那么依次加載這些依賴;
如果引入模塊失敗,那么require函數應該報一個異常;
模塊通過變量exports來向外暴露API,exports賦值暴露的只能是一個對象exports = {Obj},暴露的API須作為此對象的屬性。exports本質是引入了module.exports的對象。不能直接將exports變量指向一個值,因為這樣等于切斷了exports與module.exports的聯系。
如果暴露的不是變量exports,而是module.exports。module變量代表當前模塊,這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性。exports=module.exports={Obj}
1.安裝node.js;
2.創建項目結構
//結構如下 |-modules |-module1.js//待引入模塊1 |-module2.js//待引入模塊2 |-module3.js//待引入模塊3 |-app.js//主模塊 |-package.json { "name": "commonjsnode", "version": "1.0.0" }
3.下載第三方模塊:舉例express
npm i express --save
4.模塊化編碼
// module1 // 使用module.exports = value向外暴露一個對象 module.exports = { name: "this is module1", foo(){ console.log("module1 foo()"); } } // module2 // 使用module.exports = value向外暴露一個函數 module.exports = function () { console.log("module2()"); } // module3 // 使用exports.xxx = value向外暴露一個對象 exports.foo = function () { console.log("module3 foo()"); }; exports.bar = function () { console.log("module3 bar()"); }; exports.name = "this is module3" //app.js文件 var uniq = require("uniq"); //引用模塊 let module1 = require("./modules/module1"); let module2 = require("./modules/module2"); let module3 = require("./modules/module3"); //使用模塊 module1.foo(); module2(); module3.foo(); module3.bar(); module3.name;
5.通過node運行app.js
命令:node.app.js
工具:右鍵-->運行
借助Browserify
步驟
創建項目結構
|-js |-dist //打包生成文件的目錄 |-src //源碼所在的目錄 |-module1.js |-module2.js |-module3.js |-app.js //應用主源文件 |-index.html //瀏覽器上的頁面 |-package.json { "name": "browserify-test", "version": "1.0.0" }
下載browserify
全局: npm install browserify -g
局部: npm install browserify --save-dev
定義模塊代碼:index.html文件要運行在瀏覽器上,需要借助browserify將app.js文件打包編譯,如果直接在index.html引入app.js就會報錯。
打包處理js:根目錄下運行browserify js/src/app.js -o js/dist/bundle.js
頁面使用引入:
AMD : 瀏覽器端
CommonJS規范加載模塊是同步的,也就是說,只有加載完成,才能執行后面的操作。
AMD規范則是非同步加載模塊,允許指定回調函數,可以實現異步加載依賴模塊,并且會提前加載;
由于Node.js主要用于服務器編程,模塊文件一般都已經存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規范比較適用。
如果是瀏覽器環境,要從服務器端加載模塊,這時就必須采用非同步模式,因此瀏覽器端一般采用AMD規范。
語法定義暴露模塊: define([依賴模塊名], function(){return 模塊對象})
引入模塊: require(["模塊1", "模塊2", "模塊3"], function(m1, m2){//使用模塊對象})
define(function (require, exports, module) { var reqModule = require("./someModule"); requModule.test(); exports.asplode = function () { //someing } });AMD:異步模塊定義規范(預加載)
AMD規范:https://github.com/amdjs/amdj...
AMD是"Asynchronous Module Definition"的縮寫,意思就是"異步模塊定義"。
它采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。
AMD也采用require()語句加載模塊,但是不同于CommonJS,它要求兩個參數:
require([module], callback);
第一個參數[module],是一個數組,里面的成員就是要加載的模塊;
第二個參數callback,則是加載成功之后的回調函數。
目前,主要有兩個Javascript庫實現了AMD規范:RequireJS和curl.js。
RequireJS
優點
實現js文件的異步加載,避免網頁失去響應;
管理模塊之間的依賴性,便于代碼的編寫和維護。
下載require.js, 并引入
官網: https://requirejs.org/
中文:https://blog.csdn.net/sanxian...
github : https://github.com/requirejs/...
將require.js導入項目: js/libs/require.js
創建項目結構
|-js |-libs |-require.js // 引入的require.js |-modules |-alerter.js |-dataService.js |-main.js |-index.html
定義require.js的模塊代碼
require.js加載的模塊,采用AMD規范。也就是說,模塊必須按照AMD的規定來寫。
具體來說,就是模塊必須采用特定的define()函數來定義;
如果一個模塊不依賴其他模塊,那么可以直接定義在define()函數之中。
define(["myLib"], function(myLib){ function foo(){ myLib.doSomething(); } // 暴露模塊 return {foo : foo}; }); //當require()函數加載上面這個模塊的時候,就會先加載myLib.js文件。
- 如果這個模塊還依賴其他模塊,那么define()函數的第一個參數,必須是一個數組,指明該模塊的依賴性; ``` // dataService.js define(function () { let msg = "this is dataService" function getMsg() { return msg.toUpperCase() } return {getMsg} }) // alerter.js define(["dataService", "jquery"], function (dataService, $) { let name = "Tom2" function showMsg() { $("body").css("background", "gray") alert(dataService.getMsg() + ", " + name) } return {showMsg} }) ```
應用主(入口)js: main.js
使用require.config()方法,我們可以對模塊的加載行為進行自定義。require.config()就寫在主模塊main.js的頭部,參數就是一個對象,這個對象的paths屬性指定各個模塊的加載路徑。
(function () { //配置 require.config({ //基本路徑 baseUrl: "js/", //模塊標識名與模塊路徑映射 paths: { "alerter": "modules/alerter",//此處不能寫成alerter.js,會報錯 "dataService": "modules/dataService", } }) //引入使用模塊 require( ["alerter"], function(alerter) { alerter.showMsg() }) })()
頁面使用模塊:
require.config()接受一個配置對象,這個對象除了有前面說過的paths屬性之外,還有一個shim屬性,專門用來配置不兼容的模塊。
具體來說,每個模塊要定義:
1、exports值(輸出的變量名),表明這個模塊外部調用時的名稱;
2、deps數組,表明該模塊的依賴性。
支持的配置項:
baseUrl :所有模塊的查找根路徑。
當加載純.js文件(依賴字串以/開頭,或者以.js結尾,或者含有協議),不會使用baseUrl。
如未顯式設置baseUrl,則默認值是加載require.js的HTML所處的位置。如果用了data-main屬性,則該路徑就變成baseUrl。
baseUrl可跟require.js頁面處于不同的域下,RequireJS腳本的加載是跨域的。唯一的限制是使用text! plugins加載文本內容時,這些路徑應跟頁面同域,至少在開發時應這樣。優化工具會將text! plugin資源內聯,因此在使用優化工具之后你可以使用跨域引用text! plugin資源的那些資源。
paths:path映射那些不直接放置于baseUrl下的模塊名。
設置path時起始位置是相對于baseUrl的,除非該path設置以"/"開頭或含有URL協議(如http:)。
用于模塊名的path不應含有.js后綴,因為一個path有可能映射到一個目錄。路徑解析機制會自動在映射模塊名到path時添加上.js后綴。在文本模版之類的場景中使用require.toUrl()時它也會添加合適的后綴。
在瀏覽器中運行時,可指定路徑的備選(fallbacks),以實現諸如首先指定了從CDN中加載,一旦CDN加載失敗則從本地位置中加載這類的機制;
shim: 為那些沒有使用define()來聲明依賴關系、設置模塊的"瀏覽器全局變量注入"型腳本做依賴和導出配置。
將jquery的庫文件導入到項目: js/libs/jquery-1.10.1.js
在main.js中配置jquery路徑
paths: { "jquery": "libs/jquery-1.10.1" }
在alerter.js中使用jquery
define(["dataService", "jquery"], function (dataService, $) { var name = "xfzhang" function showMsg() { $("body").css({background : "red"}) alert(name + " "+dataService.getMsg()) } return {showMsg} })
將angular.js導入項目:js/libs/angular.js
流行的函數庫(比如jQuery)符合AMD規范,更多的庫并不符合。這樣的模塊在用require()加載之前,要先用require.config()方法,定義它們的一些特征。
// main.js中配置 (function () { //配置 require.config({ //基本路徑 baseUrl: "js/", //模塊標識名與模塊路徑映射 paths: { //第三方庫作為模塊 "jquery" : "./libs/jquery-1.10.1", "angular" : "./libs/angular", //自定義模塊 "alerter": "./modules/alerter", "dataService": "./modules/dataService" }, /* 配置不兼容AMD的模塊 exports : 指定與相對應的模塊名對應的模塊對象 */ shim: { "angular" : { exports : "angular" } } }) //引入使用模塊 require( ["alerter", "angular"], function(alerter, angular) { alerter.showMsg() console.log(angular); }) })()CMD : 瀏覽器端
CMD規范:https://github.com/seajs/seaj...
CMD規范專門用于瀏覽器端,模塊的加載是異步的,模塊使用時才會加載執行。
CMD規范整合了CommonJS和AMD規范的特點。
在 Sea.js 中,所有 JavaScript 模塊都遵循 CMD模塊定義規范
基本語法
定義暴露模塊:
// 沒有依賴的模塊 define(function(require, module, exports){ let value = "xxx"; //通過require引入依賴模塊 //通過module.exports/exports來暴露模塊 exports.xxx = value module.exports = value }) // 有依賴的模塊 define(function(require, exports, module){ //引入依賴模塊(同步) var module2 = require("./module2") //引入依賴模塊(異步) require.async("./module3", function (m3) { ...... }) //暴露模塊 exports.xxx = value })
使用模塊seajs.use(["模塊1", "模塊2"])
sea.js簡單使用教程
下載sea.js, 并引入
官網: http://seajs.org/
github : https://github.com/seajs/seajs
將sea.js導入項目: js/libs/sea.js
如何定義導出模塊 :
define() exports module.exports
如何依賴模塊:require()
如何使用模塊: seajs.use()
創建項目結構
|-js |-libs |-sea.js |-modules |-module1.js |-module2.js |-module3.js |-module4.js |-main.js |-index.html
定義sea.js的模塊代碼
module1.js
define(function (require, exports, module) { //內部變量數據 var data = "this is module1" //內部函數 function show() { console.log("module1 show() " + data) } //向外暴露 exports.show = show })
module2.js
define(function (require, exports, module) { module.exports = { msg: "I Will Back" } })
module3.js
define(function (require, exports, module) { const API_KEY = "abc123" exports.API_KEY = API_KEY })
module4.js
define(function (require, exports, module) { //引入依賴模塊(同步) var module2 = require("./module2"); function show() { console.log("module4 show() " + module2.msg) } exports.show = show //引入依賴模塊(異步) require.async("./module3", function (m3) { console.log("異步引入依賴模塊3 " + m3.API_KEY) }) })
main.js : 主(入口)模塊
define(function (require) { var m1 = require("./module1") var m4 = require("./module4") m1.show() m4.show() })
index.html:
ES6模塊化
模塊化的規范:CommonJS和AMD兩種。前者用于服務器,后者用于瀏覽器。
而ES6 中提供了簡單的模塊系統,完全可以取代現有的CommonJS和AMD規范,成為瀏覽器和服務器通用的模塊解決方案。
ES6 模塊的設計思想,是盡量的靜態化,使得編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。
基本用法
es6 中新增了兩個命令 export 和 import ;
export 命令用于規定模塊的對外接口;
import 命令用于輸入其他模塊提供的功能。
一個模塊就是一個獨立的文件。該文件內部的所有變量,外部無法獲取。
如果你希望外部能夠讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量。
下面是一個JS文件,里面使用export命令輸出變量。
// math.js export const add = function (a, b) { return a + b } export const subtract = function (a, b) { return a - b }
使用export命令定義了模塊的對外接口以后,其他JS文件就可以通過import命令加載這個模塊(文件)。
// main.js import { add, subtract } from "./math.js" add(1, 2) substract(3, 2)
定義暴露模塊 : export
暴露一個對象:
默認暴露,暴露任意數據類型,暴露什么數據類型,接收什么數據類型
export default 對象
暴露多個:
常規暴露,暴露的本質是對象,接收的時候只能以對象的解構賦值的方式來接收值
export var xxx = value1 export let yyy = value2 // 暴露一個對象 var xxx = value1 let yyy = value2 export {xxx, yyy}
引入使用模塊 : import
default模塊:
import xxx from "模塊路徑/模塊名"
其它模塊
import {xxx, yyy} from "模塊路徑/模塊名" import * as module1 from "模塊路徑/模塊名"export 詳細用法
export不止可以導出函數,還可以導出,對象、類、字符串等等;
暴露多個:
分別暴露
export const obj = {test1: ""} export const test = "" export class Test { constuctor() { } } // 或者,直接在暴露的地方定義導出函數或者變量 export let foo = ()=>{console.log("fnFoo");return "foo"},bar="stringBar"
一起暴露,推薦使用這種寫法,這樣可以寫在腳本尾部,一眼就看清楚輸出了哪些變量。
let a=1 let b=2 let c=3 export { a,b,c }
還可以通過as改變輸出名稱
// test.js let a = 1 let b = 2 let c = 3 export { a as test, b, c }; import { test, b, c } from "./test.js" // 改變命名后只能寫 as 后的命名
通過通配符暴露其他引入的模塊
// test.js let a = 1 let b = 2 let c = 3 export { a as test, b, c }; // lib.js引入test.js的內容 export * from "./test.js" // 引入 import {test,b,c} from "./lib.js"
暴露一個對象,默認暴露
export default指定默認輸出,import無需知道變量名就可以直接使用
// test.js export default function () { console.log("hello world") } //引入 import say from "./test.js" // 這里可以指定任意變量名 say() // hello world
常用的模塊
import $ from "jQuery" // 加載jQuery 庫 import _ from "lodash" // 加載 lodash import moment from "moment" // 加載 momentimport詳細用法
import 為加載模塊的命令,基礎使用方式和之前一樣
// main.js import { add, subtract } from "./test" // 對于export default 導出的 import say from "./test"
通過 as 命令修改導入的變量名
import {add as sum, subtract} from "./test" sum (1, 2)
加載模塊的全部,除了指定輸出變量名或者 export.default 定義的導入, 還可以通過 * 號加載模塊的全部。
// math.js export const add = function (a, b) { return a + b } export const subtract = function (a, b) { return a - b } //引入 import * as math from "./test.js" math.add(1, 2) math.subtract(1, 2)ES6-Babel-Browserify使用教程
問題: 所有瀏覽器還不能直接識別ES6模塊化的語法
解決:
使用Babel將ES6--->ES5(使用了CommonJS) ----瀏覽器還不能直接執行;
使用Browserify--->打包處理js----瀏覽器可以運行
定義package.json文件
{ "name" : "es6-babel-browserify", "version" : "1.0.0" }
安裝babel-cli, babel-preset-es2015和browserify
npm install babel-cli browserify -g npm install babel-preset-es2015 --save-dev
定義.babelrc文件,這是一個babel的設置文件
{ "presets": ["es2015"] }
編碼
// js/src/module1.js export function foo() { console.log("module1 foo()"); }; export let bar = function () { console.log("module1 bar()"); }; export const DATA_ARR = [1, 3, 5, 1]; // js/src/module2.js let data = "module2 data"; function fun1() { console.log("module2 fun1() " + data); }; function fun2() { console.log("module2 fun2() " + data); }; export {fun1, fun2}; // js/src/module3.js export default { name: "Tom", setName: function (name) { this.name = name } } // js/src/app.js import {foo, bar} from "./module1" import {DATA_ARR} from "./module1" import {fun1, fun2} from "./module2" import person from "./module3" import $ from "jquery" //引入完畢 $("body").css("background", "red") foo() bar() console.log(DATA_ARR); fun1() fun2() person.setName("JACK") console.log(person.name);
編譯
使用Babel將ES6編譯為ES5代碼(但包含CommonJS語法) : babel js/src -d js/lib
使用Browserify編譯js : browserify js/lib/app.js -o js/lib/bundle.js
頁面中引入測試
引入第三方模塊(jQuery)
1). 下載jQuery模塊:
npm install jquery@1 --save
- 2). 在app.js中引入并使用 ``` import $ from "jquery" $("body").css("background", "red") ```總結
模塊化方案 | 優點 | 缺點 |
---|---|---|
commonJS | 復用性強; 使用簡單; 實現簡單; |
有不少可以拿來即用的模塊,生態不錯; 同步加載不適合瀏覽器,瀏覽器的請求都是異步加載; 不能并行加載多個模塊。 |
AMD | 異步加載適合瀏覽器 | 可并行加載多個模塊; 模塊定義方式不優雅,不符合標準模塊化 |
ES6 | 可靜態分析,提前編譯 | 面向未來的標準; 瀏覽器原生兼容性差,所以一般都編譯成ES5; 目前可以拿來即用的模塊少,生態差 |
權威參考:https://github.com/seajs/seaj...
對于依賴的模塊,AMD 是提前執行,CMD 是延遲執行。
不過 RequireJS 從 2.0 開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
CMD 推崇依賴就近,AMD 推崇依賴前置。
// CMD define(function(require, exports, module) { var a = require("./a"); a.doSomething() // 此處略去 100 行 var b = require("./b") // 依賴可以就近書寫 b.doSomething() // ... }) // AMD 默認推薦的是 define(["./a", "./b"], function(a, b) { // 依賴必須一開始就寫好 a.doSomething() // 此處略去 100 行 b.doSomething() ...})
雖然 AMD 也支持 CMD 的寫法,同時還支持將 require 作為依賴項傳遞,但 RequireJS 的作者默認是最喜歡上面的寫法,也是官方文檔里默認的模塊定義寫法。
AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區分,推崇職責單一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,沒有全局 require,而是根據模塊系統的完備性,提供 seajs.use 來實現模塊系統的加載啟動。CMD 里,每個 API 都簡單純粹。
還有一些細節差異,具體看這個規范的定義就好,就不多說了。
參考:使用 AMD、CommonJS 及 ES Harmony 編寫模塊化的 JavaScript
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103478.html
摘要:收藏優秀組件庫合集前端掘金開源的優秀組件庫合集教你如何在應用程序中使用本地文件上傳圖片前端掘金使用在中添加到的,現在可以讓內容要求用戶選擇本地文件,然后讀取這些文件的內容。 『收藏』VUE 優秀 UI 組件庫合集 - 前端 - 掘金github 開源的 Vue 優秀 UI 組件庫合集?... 教你如何在 web 應用程序中使用本地文件?上傳圖片file? - 前端 - 掘金使用在HTM...
摘要:就鹿晗宣布戀情導致微博宕機事件淺談大型網站高可用性架構中午吃飯刷著刷著微博發現微博突然掛了。用戶在使用瀏覽器訪問一個網站時需要先通過協議向服務器發送請求,之后服務器返回文件與響應信息。 webpack:從入門到真實項目配置 自從出現模塊化以后,大家可以將原本一坨代碼分離到個個模塊中,但是由此引發了一個問題。每個 JS 文件都需要從服務器去拿,由此會導致加載速度變慢。Webpack 最主...
閱讀 1111·2021-11-23 09:51
閱讀 1076·2021-10-18 13:31
閱讀 2976·2021-09-22 16:06
閱讀 4263·2021-09-10 11:19
閱讀 2202·2019-08-29 17:04
閱讀 430·2019-08-29 10:55
閱讀 2477·2019-08-26 16:37
閱讀 3375·2019-08-26 13:29