距离上次写的的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原理,闭包原理之类的吧