距離上次寫的的hello world (again)有快4個月了吧,這也是過了一個學期了,藉着新年的勁頭寫下一些關於前端開發的總結吧。
關於JavaScript和V8
以chrome爲例,肯定都有了解它的運行js的引擎是一個名爲V8的引擎,但是,V8引擎和瀏覽器並不是同一個東西,chrome是在V8引擎上增加了許多的安全限制(跨域)和對象(window),所以百度出來nodejs用的就是V8引擎開發的和chrome的展現效果不同的原因就在這。
關於V8是用C++編寫的,js經過V8引擎會翻譯成C++文件再運行,相當於一個套娃c++的語言了吧🤣 。
但是,就因爲這種套娃式的語言,現在的前端開發大部分都是這種形式,通過nodejs的I/O模塊進行文件的文本讀取,然後進行下一步的解釋成html/js/css文件,再通過一些手段引用到需要用的html文件中
其實那些所謂的解釋器的插件,例如vue.js,js-yaml.js都是通過讀取字符串進行解釋的,nodejs只是提供了不用把這些需要解釋的字符串寫入html使其變得很長很複雜的條件。
nodejs和前端的關係
其實自己一開始在runoob上也有見過關於nodejs的介紹,以爲那個是後端才需要學的,真尼瑪誤導了好久一段時間了😟
垃圾runoob,但是作爲一個編程語言入門的集合的網站還是可以看看的
以前和現在的前端開發的比較
以上也說了nodejs的出現解鎖了I/O的功能,這也就成就了現在的網頁前端開發不再像以前一樣,一個html文件上寫滿了已經壓縮的或者主要的js文件
現在的開發方式就變成了模塊的方式,像是java的那種namespace下的class一樣,需要你引用相對應的namespace才能使用它以下的class,以nodejs環境下舉個🌰
目錄:
代碼:
- index.js
var A = require('./a.js')
console.log(A)
- a.js
var a = 'this is a.js!!'
module.exports = a
運行結果
但是,要注意這裏只能在nodejs環境纔有require方法和module.exports對象,在瀏覽器下直接使用index.js會出現以下問題
相對應的,瀏覽器下並沒有require方法和module.exports對象
所以,爲了讓前端一樣擁有模塊化語法的插件webpack也隨着nodejs誕生了,至今也還一直處於前端開發中的主角地位
webpack
官網
簡單來說,就是把yaml,vue,markdown等等文件通過js解釋和打包成瀏覽器可用的js文件
在上面演示的項目進行webpack打包後會生成一個主文件,沒有混淆和壓縮的情況下是這樣的
(function (modules) { // webpackBootstrap
var installedModules = {};
function __webpack_require__(moduleId) {
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
module.l = true;
return module.exports;
}
__webpack_require__.m = modules;
__webpack_require__.c = installedModules;
__webpack_require__.d = function (exports, name, getter) {
if (!__webpack_require__.o(exports, name)) {
Object.defineProperty(exports, name, { enumerable: true, get: getter });
}
};
__webpack_require__.r = function (exports) {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
__webpack_require__.t = function (value, mode) {
if (mode & 1) value = __webpack_require__(value);
if (mode & 8) return value;
if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
var ns = Object.create(null);
__webpack_require__.r(ns);
Object.defineProperty(ns, 'default', { enumerable: true, value: value });
if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) { return value[key]; }.bind(null, key));
return ns;
};
__webpack_require__.n = function (module) {
var getter = module && module.__esModule ?
function getDefault() { return module['default']; } :
function getModuleExports() { return module; };
__webpack_require__.d(getter, 'a', getter);
return getter;
};
__webpack_require__.o = function (object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
__webpack_require__.p = "";
return __webpack_require__(__webpack_require__.s = "./src/index.js");
})
({
"./src/a.js":
(function (module, exports) {
var a = 'this is a.js!!'
module.exports = a
}),
"./src/index.js":
(function (module, exports, __webpack_require__) {
var A = __webpack_require__(/*! ./a.js */ "./src/a.js")
console.log(A)
})
});
這一個文件就相當於模塊化語法環境下打包的js文件,引入html文件即可得到我們想要的結果
js模塊化
看上去一套下來感覺是好麻煩的,爲什麼不像原本那樣按順序引入js文件然後使用裏面的變量或函數那不是更簡單快捷嗎???
這其實還是涉及到了js本身的問題,js在es6以前,是沒有塊級作用域的,只有函數作用域和全局作用域,在這種情況下,js按順序引進其實還有着變量提升的問題,在一些情況下會出現變量名衝突,js並不會報錯還將新的值覆蓋舊的值上
關於js模塊化的歷程可以參考該博客
或者看這個總結:解決變量名衝突,js各個文件間的變量和函數高耦合的問題
個人小結
其實當時9月份的時候已經學會了nodejs,然而只是用來代替java作爲服務端的一個軟件,也算是懶runoob害人不淺吧,當時只是把自己限制在了前後端分離開發的階段,nodejs+express作爲傳輸json的服務端而已,開發前端在hbuilder上使用着過時的jq和bootstarp,當時並沒有想過nodejs竟然就是前端開發的主流吧,現在回想起自己寫的很自豪的那個pjax項目還真有點想笑😂hbuilder作爲自己第一個高效開發網頁的編輯器,也是因爲它的熱更新服務器的特色所吸引才用了挺久的,後面接觸了webpack才發現這東西早都有了,而且hbuilder作爲一個編輯器相對於現在用的vscode,插件少,es6語法好多都不支持!!!算是一個很失敗的東西,好的編輯器纔是前端開發前進的一個墊腳石吧。
等我不懶了,應該還會寫接下來需要說的好多的關於瀏覽器,AST,vue原理,閉包原理之類的吧