導航:首頁 > 源碼編譯 > 前端分模塊編譯

前端分模塊編譯

發布時間:2024-04-05 12:02:11

Ⅰ 如何理解前端模塊化

前端模塊化
javaScript發展初期就是為了實現簡單的頁面交互邏輯,寥寥數語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術得到廣泛應用,jQuery等前端庫層出不窮,前端代碼日益膨脹

這時候JavaScript作為嵌入式的腳本語言的定位動搖了,JavaScript卻沒有為組織代碼提供任何明顯幫助,甚至沒有類的概念,更不用說模塊(mole)了,JavaScript極其簡單的代碼組織規范不足以駕馭如此龐大規模的代碼

模塊
既然JavaScript不能handle如此大規模的代碼,我們可以借鑒一下其它語言是怎麼處理大規模程序設計的,在Java中有一個重要帶概念——package,邏輯上相關的代碼組織到同一個包內,包內是一個相對獨立的王國,不用擔心命名沖突什麼的,那麼外部如果使用呢?直接import對應的package即可

import java.util.ArrayList;
遺憾的是JavaScript在設計時定位原因,沒有提供類似的功能,開發者需要模擬出類似的功能,來隔離、組織復雜的JavaScript代碼,我們稱為模塊化。

一個模塊就是實現特定功能的文件,有了模塊,我們就可以更方便地使用別人的代碼,想要什麼功能,就載入什麼模塊。模塊開發需要遵循一定的規范,各行其是就都亂套了

規范形成的過程是痛苦的,前端的先驅在刀耕火種、茹毛飲血的階段開始,發展到現在初具規模,簡單了解一下這段不凡的歷程

函數封裝
我們在講函數的時候提到,函數一個功能就是實現特定邏輯的一組語句打包,而且JavaScript的作用域就是基於函數的,所以把函數作為模塊化的第一步是很自然的事情,在一個文件裡面編寫幾個相關函數就是最開始的模塊了

function fn1(){
statement
}

function fn2(){
statement
}
這樣在需要的以後夾在函數所在文件,調用函數就可以了

這種做法的缺點很明顯:污染了全局變數,無法保證不與其他模塊發生變數名沖突,而且模塊成員之間沒什麼關系。

對象
為了解決上面問題,對象的寫法應運而生,可以把所有的模塊成員封裝在一個對象中

var myMole = {
var1: 1,

var2: 2,

fn1: function(){

},

fn2: function(){

}
}
這樣我們在希望調用模塊的時候引用對應文件,然後

myMole.fn2();
這樣避免了變數污染,只要保證模塊名唯一即可,同時同一模塊內的成員也有了關系

看似不錯的解決方案,但是也有缺陷,外部可以隨意修改內部成員

myModel.var1 = 100;
這樣就會產生意外的安全問題

立即執行函數
可以通過立即執行函數,來達到隱藏細節的目的

var myMole = (function(){
var var1 = 1;
var var2 = 2;

function fn1(){

}

function fn2(){

}

return {
fn1: fn1,
fn2: fn2
};
})();
這樣在模塊外部無法修改我們沒有暴露出來的變數、函數

上述做法就是我們模塊化的基礎,目前,通行的JavaScript模塊規范主要有兩種:CommonJS和AMD

CommonJS
我們先從CommonJS談起,因為在網頁端沒有模塊化編程只是頁面JavaScript邏輯復雜,但也可以工作下去,在伺服器端卻一定要有模塊,所以雖然JavaScript在web端發展這么多年,第一個流行的模塊化規范卻由伺服器端的JavaScript應用帶來,CommonJS規范是由NodeJS發揚光大,這標志著JavaScript模塊化編程正式登上舞台。

定義模塊
根據CommonJS規范,一個單獨的文件就是一個模塊。每一個模塊都是一個單獨的作用域,也就是說,在該模塊內部定義的變數,無法被其他模塊讀取,除非定義為global對象的屬性

模塊輸出:
模塊只有一個出口,mole.exports對象,我們需要把模塊希望輸出的內容放入該對象

載入模塊:
載入模塊使用require方法,該方法讀取一個文件並執行,返迴文件內部的mole.exports對象

Ⅱ Web前端開發主要學哪些課程

老實說,前端經過這幾年的快速發展,網上的文章和教程還是蠻多的,有經驗的人能夠根據資料制定出屬於自己的學習方法和路徑,但對於小白來說,還是有些難度。知了姐來給大家分享前端學習路徑。針對0基礎,非科班,沒有編程經驗,想學前端,但是不知道如何入門的人群。

基礎部分:

1、HTML + CSS 這部分學習,可以模仿一些網站做些頁面,在實踐中積累經驗。做到能與UI對接,能100%重構網站靜態頁面的開發,為後期編寫頁面邏輯、動態效果打基礎。

2、Javascript 要學的內容實在很多,如果沒有其他編程語言的基礎的話,學起來可能要費些力,這個階段需要掌握編程基礎概念,培養邏輯思維能力。能夠獨立完成網站的頁面開發(包括合理布局,JavaScript操作DOM)

編譯前端和後端各有什麼特點,各自包含編譯過程的哪幾個部分

編譯前端主要包括詞法分析、語法分析、語義分析、中間代碼生成這幾個部分,後端則包含代碼優化和目標代碼生成部分。前端的特點是僅與編譯的源語言有關,而後端則僅與編譯的目標語言及運行環境有關。

將編譯過程劃分成前端和後端,主要目的是在多種源語言和多種目標語言的開發過程中,可以靈活搭配組合,消除重復開發的工作量,提高編譯系統的開發效率。

Ⅳ 編譯程序分為哪幾個主要部分

1、詞法分析

詞法分析的任務是對由字元組成的單詞進行處理,從左至右逐個字元地對源程序進行掃描,產生一個個的單詞符號,把作為字元串的源程序改造成為單詞符號串的中間程序。執行詞法分析的程序稱為詞法分析程序或掃描器。

2、語法分析

編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。

3、中間代碼生成

中間代碼是源程序的一種內部表示,或稱中間語言。中間代碼的作用是可使編譯程序的結構在邏輯上更為簡單明確,特別是可使目標代碼的優化比較容易實現。中間代碼即為中間語言程序,中間語言的復雜性介於源程序語言和機器語言之間。

4、代碼優化

代碼優化是指對程序進行多種等價變換,使得從變換後的程序出發,能生成更有效的目標代碼。所謂等價,是指不改變程序的運行結果。所謂有效,主要指目標代碼運行時間較短,以及佔用的存儲空間較小。這種變換稱為優化。

5、目標代碼生成

目標代碼生成是編譯的最後一個階段。目標代碼生成器把語法分析後或優化後的中間代碼變換成目標代碼。



(4)前端分模塊編譯擴展閱讀:

特點

數據結構分析和綜合時所用的主要數據結構,包括符號表、常數表和中間語言程序。符號表由源程序中所用的標識符連同它們的屬性組成。

其中屬性包括種類(如變數、數組、結構、函數、過程等)、類型(如整型、實型、字元串、復型、標號等),以及目標程序所需的其他信息。常數表由源程序中用的常數組成,其中包括常數的機內表示,以及分配給它們的目標程序地址。

分析部分源程序的分析是經過詞法分析、語法分析和語義分析三個步驟實現的。詞法分析由詞法分析程序(又稱為掃描程序)完成。

其任務是識別單詞(即標識符、常數、保留字,以及各種運算符、標點符號等)、造符號表和常數表,以及將源程序換碼為編譯程序易於分析和加工的內部形式。


Ⅳ 如何使用 ES6 編寫一個 React 模塊,並且編譯後發布到 NPM

如果你在使用 React, 那麼肯定已經擼了好多自己的組件, 並嘗試著共享出來。在 OneAPM 前端開發過程中, 我們也曾遇到了一些組件共享的問題:
例如:
是通過 git 直接發布還是通過 NPM 發布 ?
發布的是 ES5 的代碼還是 ES6 的代碼 ?
如何解決 Babel5 和 Babel6 的沖突 ?
這篇文章會通過編寫一個叫做 MyComponet 的例子來演示發布一個模塊需要注意的地方, 並不涉及單元測試和代碼規范等。
前端開發果真是發展迅猛,剛享受到由模塊化,組件化和單元測試帶來的種種好處,又得迅速擁抱 Grunt, Gulp, Browserify, Webpack 這類自動化工具的變革。除了工具和生態圈,JavaScript 本身也在飛速發展著。ES2015(ES6) ,ES2016(ES7) ... 照這樣的節奏,幾乎是一年一個標准。標准多了,為解決兼容性的問題,竟也派生出了 源代碼 和 編譯 的概念。前端開發者通過語法糖、轉化器、Polyfill 等,可以享受到標准乃至尚未定稿草案里的規范的便利,大幅提升開發效率。
至於這個模塊本身,它的功能特別簡單, 就是顯示模塊自身的的屬性。
源代碼
我們來編寫組件 MyComponent.jsx ,放到項目的 src 目錄下。

import React from 'react';

const MyComponent = props=> {
return <div>
props:
<pre>{JSON.stringify(props, null, 2)}</pre>
</div>
}

export default MyComponent;

關於各種文件放在哪裡, 這里是我推薦的一些約定:
src 下用於存放源代碼
lib 是編譯後的代碼,這個目錄只讀
所有包含 ES6 語法的文件名統一後綴為 .es6
所有包含 JSX 語法的文件後統一綴名為 .jsx
假設源代碼里還有另外兩個文件 foo.es6 和 bar.js,簡化起見都丟到 src 的根目錄下。
編譯
為了把 ES6 代碼編譯成 ES5,需要安裝 Babel,這個工具可以說野心極大,一次編譯可以讓 JavaScript 運行在所有地方。(聽起來是不是有點 Java 的作風)
目前最常用的是 Babel5 版本,但是 Babel6 版本的設計更為精巧,已經非常推薦更新。也正是由於 Babel 有兩個版本,所以開發過程中很有可能遇到這樣的情況,
模塊 A 的開發依賴於 Babel5 版本,而模塊 B 依賴於 Babel6 版本。
解決這個問題最好的做法就是把 A 和 B 拆開,獨立開發和發布。並且在發布到 NPM 的時候發布是的編譯後的,也就是 ES5 版本的代碼。
所以如果你的機器上的 babel 是全局安裝的,是時候卸載它了,因為它的版本不是 5 就是 6 ,會導致一些不可預見的問題。
npm uninstall babel-cli --global
正確的安裝方式是把 babel-cli 作為 develeopment 的依賴
npm install babel-cli --save-dev
使用的時候並不是直接調用全局的 Babel 而是調用依賴里的 Babel 可執行文件
./node_moles/.bin/babel
如果按照前文的約定來組織代碼,src 目錄結構看起來是這樣的

src
├── bar.js
├── foo.es6
└── MyComponent.jsx

模塊所有的代碼都在一個目錄下,這樣編譯過程就簡單多了,兩條命令就可以完成
./node_moles/.bin/rimraf lib
./node_moles/.bin/babel src ---files --source-maps --extensions .es6,.es,.jsx --out-dir lib
輸出目錄的結構

lib
├── bar.js
├── foo.js
├── foo.js.map
├── MyComponent.js
└── MyComponent.js.map

具體解釋一下各個命令的作用:
第一條命令 ./node_moles/.bin/rimraf lib
作用 編譯前清空之前的 lib 目錄,這是一個好習慣,可以杜絕對 lib 下的文件的任何手動更改。
第二條命令
./node_moles/.bin/babel src --out-dir lib --source-maps --extensions .es6,.es,.jsx ---files
作用 遍歷 src 目錄下的文件,如果後綴名是 .es/.es6/.jsx 中的一種,就編譯成 ES5,否則就直接拷貝到輸出目錄 lib 下
參數詳解:
--out-dir lib 指定輸出目錄為 lib
--extensions .es6,.es,.jsx 指定需要編譯的文件類型
---files 對於不需要編譯的文件直接拷貝
--source-maps 生成 souce-map 文件
編譯過程中還隱含了一個步驟就是載入 .babelrc 文件里的配置,該文件內容如下

{
"presets": [
"es2015",
"stage-0",
"react"
]
}

這是因為 Babel6 採用了插件化的設計,做到了靈活配置:如果要轉換 JSX 語法文件,就加上 react 的 preset,同時項目依賴里要添加
babel-preset-react

npm install babel-preset-react --save-dev

樣例代碼
開發和調試 React 模塊目前最好用的打包工具還是 Webpack,在項目跟目錄下,新建一個 example 目錄:
example/index.html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body></body>
<script src="bundle.js"></script>
</html>

example/src/index.jsx

import React from 'react';
import MyComponent,{foo,bar} from '../../';
import {render} from 'react-dom';

var element = document.createElement("div");
document.body.appendChild(element);
render(<MyComponent name="myComponent"/>, element);

webpack.config.js

var path = require('path');

mole.exports = {
entry: path.join(__dirname, 'example', 'src', 'index.jsx'),
output: {
filename: 'bundle.js'
},
mole: {
loaders: [{
test: /\.jsx$/,
loader: 'babel',
include: [
path.join(__dirname, 'example')
]
}]
},
devServer: {
contentBase: path.join(__dirname, 'example')
}
}

運行樣例代碼

./node_moles/.bin/webpack-dev-server

發布
發布前,還有一件事就是為你的模塊添加一個入口文件 index.js

mole.exports = require('./lib/MyComponent');
exports.default = require('./lib/MyComponent');
exports.bar = require('./lib/bar');
exports.foo = require('./lib/foo');

接下來就是發布到 NPM 了。

npm publish

使用
別的開發者在使用你新發布的模塊的時候可以這樣導入

import MyComponent,{foo,bat} from 'react-component-example'

導入的直接是 ES5 代碼,跳過編譯從而避免了出現 Babel 版本不一致的問題,並且速度更快,是不是很棒!
不過假設你的模塊包含很多組件,開發者可能只想用其中的一個或某幾個,這時可以這樣導入:

import MyComponent from 'react-component-example/src/MyComponent.jsx'

導入的是 ES6 代碼,並且會被加入父級項目的編譯過程。

閱讀全文

與前端分模塊編譯相關的資料

熱點內容
我的世界如何編程 瀏覽:84
vue反編譯代碼有問題 瀏覽:948
linuxshell字元串連接字元串 瀏覽:51
androidviewpager刷新 瀏覽:438
python編程計算平均分 瀏覽:678
加密數字貨幣市值查詢 瀏覽:692
時尚商圈app怎麼樣 瀏覽:584
stacklesspython教程 瀏覽:138
用命令行禁用135埠 瀏覽:212
linux防火牆編程 瀏覽:627
pdf閱讀器刪除 瀏覽:979
考研人如何緩解壓力 瀏覽:822
買電暖壺哪個app便宜 瀏覽:505
洛克王國忘記伺服器了怎麼辦 瀏覽:782
為什麼cf登錄伺服器沒反應 瀏覽:695
伺服器如何獲取文件列表 瀏覽:672
creo五軸編程光碟 瀏覽:14
蘋果app網路驗證在哪裡 瀏覽:14
博科清空命令 瀏覽:384
簡愛英文pdf 瀏覽:376