摘要:不用我贅述,前端開發(fā)人員一定耳熟能詳。命令會用這個配置,生成的結(jié)果都會給文件名加,文件也會壓縮??捎霉ぞ呓榻B啟動調(diào)試服務(wù)器,使用作為配置,不直接生成物理文件,直接內(nèi)存級別響應(yīng)調(diào)試服務(wù)器資源請求。
AngularJS不用我贅述,前端開發(fā)人員一定耳熟能詳。有人稱之為MVWhatever框架,意思是使用AngularJS,你可以參考任意范式進(jìn)行應(yīng)用開發(fā),無論是MVC、還是MVVVM都信手拈來,只要你懂,范式在AngularJS手下,都可以輕松適配。
隨著各種現(xiàn)代瀏覽器、以及node對ES6的支持,已經(jīng)有越來越多的ES6特性可以在程序中使用,她們給開發(fā)過程帶來的便利不言而喻,舉個小例子,我想從一個數(shù)組里找一些符合條件的數(shù)據(jù),放入另一個數(shù)組內(nèi),過去我們這么寫:
var list = [], i; for (i = 0; i < originalList.length; i++) { var item = originalList[i]; if (item.gender === "male") { list.push(item); } } console.log(list); //符合條件的新數(shù)組
如果改用數(shù)組的高階函數(shù),再配合ES6的arrow function,代碼可以簡潔如斯:
const list = originalList.filter(item => item.gender === "male"); console.log(list); //符合條件的新數(shù)組
既然有如此優(yōu)雅的語法糖能讓我們的開發(fā)變得high到爆,那過去我們認(rèn)為屌炸天的AngularJS(現(xiàn)在也屌炸天,只不過還有Angular2, React, vue橫空出世)是不是可以用ES6來寫?少年不要懷疑,真的可以哦!
一個良好、快速、簡潔的starter工具有利于我們對ES6編寫AngularJS的深入認(rèn)知,所以我要用一個骨架生成器generator-es6-angular來創(chuàng)建新項(xiàng)目,該generator是依托于yeoman的腳手架。
安裝yonpm install -g yo
安裝generator-es6-angular請注意前綴sudo,如果你使用的是unix like操作系統(tǒng)的話
npm install -g generator-es6-angular
使用generator-es6-angular創(chuàng)建項(xiàng)目請注意前綴sudo,如果你使用的是unix like操作系統(tǒng)的話
先找個你喜歡的目錄,然后運(yùn)行下面的命令,因?yàn)橐粫马?xiàng)目會直接創(chuàng)建在該目錄下。
yo es6-angular
上面命令回車后,生成器會問你如下問題,老實(shí)作答即可(注意: 對單頁應(yīng)用沒經(jīng)驗(yàn)的孩紙,在Use html5 model這個問題上,請選擇No; 當(dāng)問你Which registry would you use?時,國內(nèi)用戶選擇第一個淘寶鏡像安裝速度會快很多)
當(dāng)命令執(zhí)行完畢后,你就能在當(dāng)前目錄下看到剛才創(chuàng)建的項(xiàng)目了,本例中我使用的project name是es6-demo。
開啟調(diào)試之旅#進(jìn)入剛創(chuàng)建的項(xiàng)目目錄 cd es6-demo #啟動調(diào)試服務(wù) npm start
然后你就可以在http://localhost:8080下,看到剛創(chuàng)建的項(xiàng)目的運(yùn)行效果了:
項(xiàng)目簡介 骨架結(jié)構(gòu)es6-demo ├── etc │?? └── config.js ├── img │?? └── ... ├── js │?? ├── features │?? │?? ├── about │?? │?? │?? ├── components │?? │?? │?? │?? ├── about.co │?? │?? │?? │?? ├── about.css │?? │?? │?? │?? └── subs │?? │?? │?? │?? ├── more │?? │?? │?? │?? │?? ├── index.co │?? │?? │?? │?? │?? └── more.css │?? │?? │?? │?? └── why │?? │?? │?? │?? ├── index.co │?? │?? │?? │?? └── why.css │?? │?? │?? ├── main.js │?? │?? │?? └── routes.js │?? │?? ├── common │?? │?? │?? ├── components │?? │?? │?? │?? ├── main.js │?? │?? │?? │?? ├── menu.co │?? │?? │?? │?? └── menu.css │?? │?? │?? ├── directives │?? │?? │?? │?? ├── autofocus.js │?? │?? │?? │?? └── main.js │?? │?? │?? ├── main.js │?? │?? │?? └── runners │?? │?? │?? ├── main.js │?? │?? │?? └── routeIndicator.js │?? │?? ├── home │?? │?? │?? ├── components │?? │?? │?? │?? ├── home.co │?? │?? │?? │?? └── home.css │ │ │ │ │?? │?? │?? ├── main.js │?? │?? │?? ├── routes.js │?? │?? │?? └── service │?? │?? │?? └── HomeService.js │?? │?? └── main.js │?? ├── fw │?? │?? ├── config │?? │?? │?? ├── SSOConfig.js │?? │?? │?? ├── main.js │?? │?? │?? └── routerConfig.js │?? │?? ├── ext │?? │?? │?? └── main.js │?? │?? ├── helper │?? │?? │?? ├── event.js │?? │?? │?? ├── ngDeclare.js │?? │?? │?? └── object.js │?? │?? └── value │?? │?? ├── main.js │?? │?? └── routesValue.js │?? ├── application.co │?? ├── application.css │?? ├── index.js │?? └── main.js ├── index.html_vm ├── package.json ├── postcss.config.js ├── webpack.config.js └── webpack.config.prod.js
etc, 一些公共配置性內(nèi)容,可以放在這里,方便查找、通用
img, 用我多說么?放圖片的啦
js, 分為features和fw兩大部分。這個內(nèi)容略多,我后面詳述吧。
index.html_vm, 單頁應(yīng)用html模版,最終的html會由webpack根據(jù)這個模版生成
package.json, 項(xiàng)目的npm描述文件,那些具體的工具命令(譬如剛才用過的npm start,都在這里面定義好了)
postcss.config.js, postcss的配置文件
webpack.config.js, 開發(fā)、調(diào)試環(huán)境使用的webpack配置
webpack.config.prod.js, 正式運(yùn)行環(huán)境使用的webpack配置。npm run release命令會用這個配置,生成的結(jié)果都會給文件名加hash,javascript文件也會壓縮。
可用工具介紹npm start, 啟動調(diào)試服務(wù)器,使用webpack.config.dev.js作為webpack配置,不直接生成物理文件,直接內(nèi)存級別響應(yīng)調(diào)試服務(wù)器資源請求。而且內(nèi)置hot reload,不用重啟服務(wù),修改源碼,瀏覽器即可刷新看到新效果
npm run release, 使用webpack.config.prod.js作為webpack配置,生成壓縮、去緩存化的bundle文件到es6-demo/build目錄下。也就是說,如果你要發(fā)布到生產(chǎn)環(huán)境或者其它什么測試環(huán)境,你應(yīng)該提供的是es6-demo/build目錄下生成的那堆東西,而不是源碼。
js目錄介紹 featurescommon
那些通用的組件、指令、過濾器、服務(wù)。。。通通應(yīng)該放在這里,譬如為了演示方便,我已經(jīng)在features/common/directives里寫了一個autofocus.js的指令,拿去用,不要客氣。代碼如下:
export default { type: "directive",//聲明這是一個指令 name: "autofocus",//聲明指令名 //聲明指令構(gòu)造函數(shù),詳見:https://docs.angularjs.org/api/ng/type/angular.Module#directive directiveFactory: function() { "ngInject"; return { restrict: "A", link($scope, element) { element[0].focus(); } }; } };
同時當(dāng)然也可以聲明諸如:組件、過濾器之類的公共工具,詳見:common
about
home
這兩個就是純粹為了演示“功能 <對應(yīng)> 路由”這個小原則而做的,你可以分別在這兩個feature下找到一個routes.js,里面的內(nèi)容就描述了該功能對應(yīng)一個(或多個)路由,是何等的easy。至于最后這個路由會怎樣被這個骨架使用,小伙伴們,好好研究哦!
fw這里面都是些所謂"框架"級別的設(shè)置,有興趣的話挨個兒打開瞧瞧嘛,沒什么大不了的。
源碼介紹 js/index.js特別注意,大部分時候,你的開發(fā)都應(yīng)該圍繞features目錄展開,之所以叫fw,就是和具體業(yè)務(wù)無關(guān),除非你需要修改框架啟動邏輯,路由控制系統(tǒng)。。。,否則不需要動這里的內(nèi)容
入口文件
/** * * 這里連用兩個ensure,是webpack的特性,可以強(qiáng)制在bundle時將內(nèi)容拆成兩個部分 * 然后兩個部分還并行加載 * */ //第一個部分是一個很小的spinner,在并行加載兩個chunk時,這個非常小的部分90%會競速成功 //于是你就看到了傳說中的loading動畫 require.ensure(["splash-screen/dist/splash.min.css", "splash-screen"], function(require) { require("splash-screen/dist/splash.min.css").use(); require("splash-screen").Splash.enable("circular"); }); //由于這里是真正的業(yè)務(wù),代碼多了太多,所以體積也更大,加載也更慢,于是在這個chunk加載完成前 //有個美好的loading動畫,要比生硬的白屏更優(yōu)雅。 //放心,這個chunk加載完后,loading動畫也會被銷毀 require.ensure(["css/main.css", "splash-screen", "./main"], function(require) { require("css/main.css").use(); //這里啟動了真正的“框架” var App = require("./main").default; (new App()).run(); });js/main.js
“框架”啟動器
//引入依賴部分 import angular from "angular"; //引入Object幫助庫 import {pluck} from "./fw/helper/object"; //引入feature注冊工具 import {declareFeatures, declareValues, declareDirectives, declareComponents, declareRunners, declareFilters} from "./fw/helper/ngDeclare"; //引入三方依賴 import Extensions from "./fw/ext/main"; //引入項(xiàng)目配置 import Configurators from "./fw/config/main"; //引入項(xiàng)目常量設(shè)置 import Values from "./fw/value/main"; //引入features import Things from "./features/main"; //引入根組件 import Application from "./application"; //引入啟動spinner控制器 import {Splash} from "splash-screen"; class App { constructor() { //這里相當(dāng)于ng-app的名字 this.appName = "es6-demo"; //找到所有的features this.features = Things.filter(t => t.type === "feature" && t.name); } //檢查項(xiàng)目基本設(shè)置 validate() { if (!this.features || this.features.length === 0) { return console.warn("No features loaded"); } const modNames = pluck(this.features, "name").sort(); for (let i = 0; i < modNames.length - 1; i++) { if (modNames[i] === modNames[i + 1]) { throw new Error("Duplicated Module: [ " + modNames[i] + " ], you have to specify another name"); } } } //從features實(shí)例中提取AngularJS module name //并將這些name作為es6-demo的依賴 //會在下面createApp時用到 findDependencies() { this.depends = [...Extensions, ...this.features.map(f => f.name)]; } //創(chuàng)建angular應(yīng)用 createApp() { declareFeatures(this.features); this.app = angular.module(this.appName, this.depends); this.app.component("application", Application); } //配置es6-demo configApp() { Configurators.forEach(Configurator => { this.app.config(Configurator.config); }); } //注冊fw下的“框架”級service registerServices() { declareValues(this.app, Values); declareDirectives(this.app, Things.filter(t => t.type === "directive")); declareComponents(this.app, Things.filter(t => t.type === "component")); declareRunners(this.app, Things.filter(t => t.type === "runner")); declareFilters(this.app, Things.filter(t => t.type === "filter")); } //看到了么,這里我會銷毀loading動畫,并做了容錯 //也就是說,即便你遇到了那微乎其微的狀況,loading動畫比業(yè)務(wù)的chunk加載還慢 //我也會默默的把它收拾掉的 destroySplash() { Splash.destroy(); require("splash-screen/dist/splash.min.css").unuse(); setTimeout(() => { if (Splash.isRunning()) { this.destroySplash(); } }, 100); } //啟動AngularJS app launch() { angular.bootstrap(document, [this.appName]); } //順序激活所有模塊 run() { this.validate(); this.findDependencies(); this.createApp(); this.configApp(); this.registerServices(); this.destroySplash(); this.launch(); } } export default App;用ES6寫Feature
features/home/main.js
//引入路由 import routes from "./routes"; //引入所有本feature中要用到的組件 import home from "./components/home"; import logo from "./components/subs/logo"; import description from "./components/subs/description"; import github from "./components/subs/github"; import todoApp from "./components/subs/todo"; import footer from "./components/subs/footer"; //引入本feature中要用到的service import HomeService from "./service/HomeService"; export default { type: "feature",//聲明該模塊是一個feature name: "home",//聲明feature的名字,必須的 routes,//倒入路由 component: {//注冊所有用到的組件 home, logo, description, github, todoApp, footer }, service: {//注冊所有用到的service HomeService } };用ES6寫路由
簡單到?jīng)]朋友
export default [ { id: "home",//為該路由起一個唯一標(biāo)識符 isDefault: true,//聲明是否為默認(rèn)路由 when: "/home",//路由路徑 template: "用ES6寫"http://路由對應(yīng)組件 } ];
//引入該組件對應(yīng)的css,注意這里不會有像vue那樣的作用域, //不過能幫助你分離css內(nèi)容,也不錯的 import "./home.css"; //導(dǎo)出組件聲明對象 export default { template: ``, controller: class { //下面是依賴注入的關(guān)鍵,通過https://github.com/schmod/babel-plugin-angularjs-annotate實(shí)現(xiàn) /*@ngInject*/ constructor(HomeService) { this.HomeService = HomeService; this.todos = []; this.loading = true; } $onInit() { this.HomeService .getInitTodos() .then(todos => { this.todos = todos; this.loading = false; }); } addTodo(todo) { this.todos = [todo, ...this.todos]; } toggleTodo(todo) { this.todos = this.todos.map(t => { if (t.txt !== todo.txt) { return t; } return { finished: !todo.finished, txt: t.txt }; }); } archive() { this.todos = this.todos.filter(todo => !todo.finished); } $onDestroy() {} } };
最后,你可能還有其它問題,直接來看看這里,或者Github上給我提issue也未嘗不可呢
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79410.html
摘要:簡介前端發(fā)展迅速,開發(fā)者富有的創(chuàng)造力不斷的給前端生態(tài)注入新生命,各種庫框架工程化構(gòu)建工具層出不窮,眼花繚亂,不盲目追求前沿技術(shù),學(xué)習(xí)框架和庫在滿足自己開發(fā)需求的基礎(chǔ)上,然后最好可以對源碼進(jìn)行調(diào)研,了解和深入實(shí)現(xiàn)原理,從中可以獲得更多的收獲隨 showImg(https://segmentfault.com/img/remote/1460000016784101?w=936&h=397)...
摘要:歡迎使用中文文檔架構(gòu)概覽是網(wǎng)易項(xiàng)目團(tuán)隊(duì)開發(fā)的一個基于進(jìn)行開發(fā)的應(yīng)用層框架,提供了一個輕量級的容器來編寫簡單可維護(hù)的。 JavaScript 可以……嘛,不就是操作一下 DOM,可以讓元素飛來飛去嗎JavaScript 是……不就是用 jQuery 讓網(wǎng)頁動起來,頂多就是再用用 Ajax 和后端進(jìn)行一下數(shù)據(jù)交換嗎JavaScript 是一門……最討厭和鄙視這種弱類型不需要編譯的腳本語言...
摘要:它不僅從前端移動到后端,我們也開始看到它用于機(jī)器學(xué)習(xí)和增強(qiáng)現(xiàn)實(shí),簡稱。由于其高使用率,年的現(xiàn)狀調(diào)查將其稱為采用的安全技術(shù)。機(jī)器學(xué)習(xí)框架在年的開發(fā)者峰會上,宣布了他們的機(jī)器學(xué)習(xí)框架的實(shí)現(xiàn),稱為。更高級別的用于在之上構(gòu)建機(jī)器學(xué)習(xí)模型。 2019,開發(fā)者應(yīng)該學(xué)習(xí)的16個JavaScript框架 showImg(https://segmentfault.com/img/remote/14600...
摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
流行框架 簡介 angularjs是一款非常優(yōu)秀的前端高級JS框架,由谷歌團(tuán)隊(duì)開發(fā)維護(hù),能夠快速構(gòu)建單頁web應(yīng)用,化繁為簡 無論是angularjs還是jQuery都是用原生JS封裝的 庫:對代碼進(jìn)行封裝,調(diào)用封裝的方法,簡化操作 傳統(tǒng)方式是用get方式獲取元素,然后點(diǎn)方法 jQuery庫實(shí)現(xiàn)了對獲取方式的封裝,對方法的封裝 框架:提供代碼書寫規(guī)則,按照規(guī)則去寫代碼,框架會幫我們實(shí)現(xiàn)響應(yīng)的功能...
閱讀 3777·2023-04-25 20:00
閱讀 3123·2021-09-22 15:09
閱讀 519·2021-08-25 09:40
閱讀 3429·2021-07-26 23:38
閱讀 2214·2019-08-30 15:53
閱讀 1103·2019-08-30 13:46
閱讀 2801·2019-08-29 16:44
閱讀 2056·2019-08-29 15:32