手把手深入理解 webpack dev middleware 原理與相關 plugins
手把手深入理解 webpack dev middleware 原理與相關 plugins
本文將對 webpack 周邊的 middleware 與 plugin 套件等作些介紹,若您對於 webpack 還不了解可以參考這篇彙整的翻譯。
webpack dev server 是什麼?
webpack dev server
是一個開發伺服器,內建 webpack 使用的 live reloading 功能。
那 webpack dev middleware 是啥?
它就是一個用來組織包裝 webpack 使其可以變成中介軟體,或稱中間件的容器。回想一下 express 你大概可以明白關於 middleware 的用途,就是在輸入到輸出的過程中 加工
的一種手段。單純說 middleware 的話我們可以想成一系列任務, 動作
(actions stack),不只 express 有,在 Ruby 中的 rake 也具備這種機制。
先看看web dev server的說明
The webpack-dev-server is a little node.js Express server, which uses the webpack-dev-middleware to serve a webpack bundle.
從頭說起的話就是 webpack
本身只負責打包編譯的功能 bundle
, webpack-dev-server
當然就是協助我們開發的伺服器,這個伺服器底層是靠 express 來實作的,接著思考一下我們要如何更新(live reload)呢? 當然是需要取得 webpack 編好的資料啊,於是就需要在從 request
到 response
的過程中透過 express 的 middleware 取得資料,而方法就是透過 webpack-dev-middleware 。
比起直接編譯成檔案,webpack-dev-middleware 這個套件還多了一些好處:
webpack hot middleware 是什麼?
我們都知道 webpack dev server 有提供一種Hot Module Replacement/Hot Reloading
熱替換的功能。在一般 webpack-dev-server
的時候我們會在 webpack.config.js
加入 new webpack.HotModuleReplacementPlugin()
或設定來啟用。
而 webpack hot middleware 是給 webpack-dev-middleware
用的。就是讓我們在一般的 server 上加上熱替換的功能,總結來說就是 webpack-dev-middleware
+ webpack-hot-middleware
即可讓我們用 express 客製一個有熱替換功能的 webpack 開發伺服器。
使用 webpack-dev-server 當中介軟體
webpack 提供了 express 的 middleware 讓我們可以處理一些靜態資源檔而不是使用 express.static
。要達成這項功能,我們需要安裝 webpack-dev-middleware
和 webpack-hot-middleware
$ npm i webpack express webpack-dev-middleware webpack-hot-middleware -D
安裝完成套件之後,首先我們需要設定一個 webpack.dev.config.js
檔案,並且在 entry
中加上 webpack/hot/dev-server
和 webpack-hot-middleware/client
entry: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'client/index.js'
]
這個 webpack.config
主要是給開發伺服器用的,由於這時的匯出都會存在記憶體中,因此 path
可以直接設為根
output: {
path: '/',
publicPath: 'http://localhost:8080/scripts/',
filename: 'bundle.js'
}
最後補上任何您所需要的 loaders,最重要的是記得。
plugins: [
new webpack.HotModuleReplacementPlugin()
]
接著下來我們開始來撰寫這個開發環境的設定檔和 express 程式。
我們會匯入 webpack,webpack-dev-middleware, webpack-hot-middleware 和 express。
若需要搭配樣板引擎請自行安裝 ejs 或 jade
var express = require('express')
var webpack = require('webpack')
var WebpackDevMiddleware = require('webpack-dev-middleware')
var WebpackHotMiddleware = require('webpack-hot-middleware')
載入套件之後,使用 express 建立一個 http 應用程式與路由
app = express()
router = express.Router()
router.get('/', MainController)
app.use(router)
上面只是一個一般的 Server 應用,為了達成 webpack 的神奇黑魔法我們需要匯入 webpack 的設定
var config = require('./webpack.dev.config')
webpack 的角色就是我們的編譯器,透過下面的程式碼建立編譯器的 instance
var compiler = webpack(config)
重點來了,我們有了伺服器 express,有了編譯核心 webpack,接著我們需要 wrapper 來打包 webpack 將其合進 express 的 middleware stack 中。
app.use(WebpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
stats: { colors: true }
}))
publicPath
就是我們想要存取前端 bundle 的網址,路徑,位置。然後我們要再加上 webpack-hot-middleware 使其具備熱替換的功能。
app.use(WebpackHotMiddleware(compiler, {
log: console.log
}))
最後則是 express 的監聽事件
app.listen(8080, function () {
console.log('Listening on 8080')
})
完整的 server 程式碼如下
var express = require('express')
var webpack = require('webpack')
var WebpackDevMiddleware = require('webpack-dev-middleware')
var WebpackHotMiddleware = require('webpack-hot-middleware')
var config = require('./config/webpack.dev.config')
var compiler = webpack(config)
app = express()
app.set('views', './views')
app.set('view engine', 'ejs')
app.use(express.static('public'));
app.use(WebpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
stats: { colors: true }
}))
app.use(WebpackHotMiddleware(compiler))
var router = express.Router()
router.get('/', function (req, res, next) {
res.render('index', { message: 'Hey there!'});
})
app.use(router)
app.listen(8080, function () {
console.log('Listening on 8080')
})
換個思路
假設我們並不是要實作一個全站 SPA 的站,實務上我們的確會遇到需要拆分為許多 view .html
的狀況,這種情況下我們會希望自己客製的這個 server 就像 webpack-dev-server
一樣,當然,這邊只是要指出做法,如果一樣您當然就直接用 webpack-dev-server 就好了。
根據上面這個需求最簡單的方式就是透過 express.static(__dirname)
讓 express 直接 return raw 檔案。
html-webpack-plugin
小弟認為在學習的過程中,最重要的就是搞懂動機,而這個 html-webpack-plugin
插件,其用途就是簡化建立 html 的過程。
先回頭看看上一小節,很直覺的,我們會依據需求建立不同的頁面(.html)
,因為在開發過程中很多時候前端只需要注重那些互動介面的邏輯
,樣式
,樣板
,標籤結構
,那我們的重點只有 client 端的 html, js, css 就不在話下了吧!再如果我們又以元件
為思路中心來設計實踐的話,那麼 html 裡面大部分的東西都會往元件的 template 搬。依據 SPA 的思路,html 的責任就只是把我們的 bundle 載入並掛載 root component
。
如果照著這樣的想法,不斷的新增 html 結果大部分的內容都是重複的那就不太靠譜啦。我們就需要一種簡化工作的方式。
這個套件如上面所說就是簡化建立載入 bundle 的 html
的步驟,用在 webpack 打包的檔案包含每次編譯都會更新的 hash 時特方便。
我們可以讓套件幫我們產生 html 或者搭配 loaders 與其他樣版引擎。
基本的用法
第一種最簡單的用途就是為我們的 bundle 包上一層 html
plugins: [
new HtmlWebpackPlugin({
filename: 'i_love_this_file.html'
})
]
如果我們有多個 entry
進入點,那麼所有的 bundle 都會被加進這個自動產生的 HTML 中。 如果我們透過 webpack 匯出了 css 資源檔(例如 extract-text-plugin) 那麼這些檔案也會透過
被加入 HTML 中。
html-webpack-plugin 的設定
當然這個套件也有一些參數,讓我們可以透過設定提供其他的功能。
title
: 設定該 html 的
標籤
filename
: html 檔名,也當作路徑存取。預設是 index.html
template
: 樣板的路徑,也就是說我們可以先組織 HTML 在載入讓 html-webpack-plugin
幫我們注入(inject) bundle。此部分要注意相對路徑是從 server 程式檔案出發。
inject
: 將所有的資源檔注入 template
或 templateContent
,當值是 true
, 'body'
的時候所有的 js 資源檔都會被注入
之前,'head'
則是
之間,false
自然就是關閉
true: Boolean
false: Boolean
head: String
body: String
favicon
: 替 HTML 加上 favicon 路徑
minify
: 傳入 html-minifier 參數物件,壓縮輸出。
options: Object
false: Boolean
hash
: true
時替 webpack 編譯的檔案或結果路徑結尾補上 hash,這麼做的用意是在開發時期當檔案有異動時可以避免瀏覽器快取
true: Boolean
false: Boolean
cache
: 預設是 true
快取檔案,除非檔案有異動
true: Boolean
false: Boolean
showErrors
: 預設 true
例外或錯誤資訊會寫入 html 頁面
true: Boolean
false: Boolean
chunks
: 允許我們加入一些程式碼片段,例如單元測試
chunksSortMode
: 控制 chunks 排序
none: String
auto: String
dependency: String
{}: Function
excludeChunks
: 略過部分 chunk 程式碼片段
xhtml
: 設定為 true
的話 link
標籤會是 self-closing ,預設是 false
true: Boolean
false: Boolean
腦力激盪 - 如果要多個頁面搭配各自的 bundle?
webapck 難就難在其靈活之中伴隨著複雜,不同的思路有著不同的做法。這一小節目的是為了不讓我們對 webpack 使用上僵化而提出的一個小題目。
要達成這個需求,我們可以先使用 webpack.config 中 [name]
的功能拆分我們的 bundle
{
entry: {
a: './path/src/a',
b: './path/src/b',
c: './path/src/c'
},
output: {
filename: '[name].bundle.js'
}
}
接著透過 html-webpack-plugin
的參數,把 inject: false
然後 template
在各自的 template 中使用 bundle。
html-webpack-template - 更牛的方式
照著上面的方式你可能又跟我抱怨,那不是又要產一堆 HTML 了嗎? 對啊!原本這個架構就是針對 SPA 設計的嘛。不過透過這樣來來回回的思考動機與流程我相信對於您日後使用 webpack 與閱讀設定有很大的幫助。現在的問題是 - 你覺得產一大堆 HTML 不是很靠譜,於是我們就有了 html-webpack-template
的產生啦。
這個東西大略的用法就是
plugins: [
new HtmlWebpackPlugin({
title: 'Sample',
filename: 'sample.html'
}),
new HtmlWebpackPlugin({
inject: false, // 必須
template: require('html-webpack-template'), // 必須
filename: 'sp.html', // 存取的路徑
// 只需要特定 bundle 可以這樣設定
chunks: ['vender'],
title: 'OH My Gosh',
// 可以參考 html-webpack-template 的參數設定
// 下面為提供 GA
googleAnalytics: {
trackingId: 'UA-XXXX-XX',
pageViewOnLoad: true
}
})
]
html-webpack-plugin 事件
特地介紹此套件的事件也是因為挺有可能會需要一些時間點對 html 動些手腳,有了事件的機制我們就可以讓其他套件
修改產生的 html
非同步事件:
html-webpack-plugin-before-html-generation
html-webpack-plugin-before-html-processing
html-webpack-plugin-after-html-processing
html-webpack-plugin-after-emit
同步事件:
大略的用法就是在透過 hook event 綁定的事件做些處理
compiler.plugin('compilation', function(compilation) {
console.log('The compiler is starting a new compilation...');
compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {
htmlPluginData.html += 'The magic footer';
callback(null, htmlPluginData);
});
});
webpack-hot-middleware
webpack-hot-middleware
這個套件只能搭配 webpack-dev-middleware
使用,其實就是把熱替換的功能加到一般 server 應用。
這個模組只專注在處理 webpack 和瀏覽器溝通的機制。這個中介軟體會去訂閱監聽開發伺服器,當更新或異動發生的時候它就透過 webpack 的 HMR API 來更新。實際上讓您的程式能無縫的使用熱替換已超過本文範圍,在這部分通常會靠其他模組來處理。
安裝完套件與在伺服器 app 中套用之外,要記得 webpack.config 的 plugin 也要加上 HotModuleReplacementPlugin
plugins: [
// Webpack 1.0
new webpack.optimize.OccurenceOrderPlugin(),
// Webpack 2.0 fixed this mispelling
// new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
簡短地介紹一下 OccurrenceOrderPlugin
部份,您應該知道 webapck 會給編譯好的程式碼片段一個 id 以用來辨別。
透過上面的這個 plugin 可以讓 webpack 在 id 的分派上優化並保持一致性。
接著要在 entry point 加上 webpack-hot-middleware/client
這隻檔案會連到 server 目的是當 server 重新編譯好檔案時收到通知然後更新 client 的檔案。
如何撰寫 plugin
為什麼要了解怎麼寫 plugin 呢? 因為某些 plugin 可以擴展支援其他 plugin 相互傳遞資料或需要客製後續任務,所以稍微明白 plugin 的寫法可以讓我們對於 plugin 的設定更加清楚。
plugin 的架構設計促使第三方開發者讓 webpack 核心發揮出無限的潛力。在不同建置階段執行 callback ,開發者可以自訂出特有的行為。
當然建置 plugin 比起開發 loader 是較進階的議題,因為我們必須要理解 webpack 內部的一些 hook 事件。
編譯器與編譯結果
要開發 plugin 第一步就是先了解其中最重要的兩個角色 compiler
和 compilation
物件
compiler
編譯器物件代表一個完整設定的 webpack 環境。這個物件在 webpack 發動之後就會被建置,而且只會建置一次。然後它會配置所有可以操作的設定包含 loaders
, plugins
。當我們套用一個 plugin 這個 plugin 會收到 compiler
的參考透過存取這個參考 reference
就可以取得 webpack 環境
compilation
編譯成果這個物件代表的是某個版本的編譯後的資源檔
,在運行 webpack dev middleware 期間每當檔案發生異動就會產生一個新的 compilation
也就是產生新的編譯結果。這個編譯結果
包含的訊息包含 module 模組的狀態,編譯後的資源檔,發生異動的檔案,被觀察的相依套件等。這個編譯結果物件也提供一些執行 callback 的機會讓我們可以在過程中客製一些自己想要的行為。
任何 webpack plugin 都必須依靠這兩者來完成,所以有需要對其原始碼有些大概的了解
Compiler Source
Compilation Source
基本 plugin 架構
本質上來說 plugin 只是一個物件實例具有 apply 方法,這個 apply
會在安裝時期被 webpack compiler
執行一次。
透過這一次的執行呢我們就可以繫結許多事件,直接來看看程式碼您就明白了。
function MyPlugin(options) {
// 設定參數
this.options = options
}
MyPlugin.prototype.apply = function(compiler) {
compiler.plugin('done', function() {
// 當 plugin 安裝完成就會...
console.log('Hello World!');
})
// 我們自然需要拿到編譯的結果
compiler.plugin("compilation", function(compilation) {
console.log(compilation.assets)
compilation.plugin("optimize", function() {
console.log("Assets are being optimized.");
});
});
}
OK! 我們現在並不是要開發套件所以點到這邊我想就足夠了,剩下的您可以自行參考相關文件。
extract-text-webpack-plugin
顧名思義這個 plugin 的用途就是把 text 類型的結果匯出成一個檔案,先說這不是非常精確的描述,但概念來說 text 類型指的就是不會
輸出成 module.exports
或 json
的資料。而像是 CSS 這類的資源檔 webpack 其實最終就是在 JS 中幫我們建個 style tag 的 dom 然後整包放進去。file-loader
, raw-loader
等等這類內容大略就屬於 text 類型。查閱各種 loaders 回傳資料類型
於是乎以 entry point 為單位過程中解析的 text 內容就會被抽出來匯出成一個檔案。最常見的用法就是把 css 抽出來:
var ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style", "css") }
]
},
plugins: [
// 注意: 這邊的副檔名如果亂下是會造成瀏覽器行為不符合預期的,例如不給副檔名那瀏覽器就會當作 binary 下載
new ExtractTextPlugin("styles.css")
]
}
如果想要拆分多個檔案,那麼就先初始化 instance
let ExtractTextPlugin = require('extract-text-webpack-plugin');
// multiple extract instances
let cssExtractor = new ExtractTextPlugin('stylesheets/[name].css');
let lessExtractor = new ExtractTextPlugin('stylesheets/[name].less');
module.exports = {
module: {
loaders: [
{test: /\.scss$/i, loader: cssExtractor.extract(['css','sass'])},
{test: /\.less$/i, loader: lessExtractor.extract(['css','less'])},
...
]
},
plugins: [
cssExtractor,
lessExtractor
]
}
HMR 熱替換
Hot Module Replacement (HRM) 又稱熱替換,功能就是在程式運行中交換,移除,增加模組且不會使頁面重新載入。這跟我們伺服器的熱插拔差不多概念。
它是怎麼運作的?
webpack 在 bundle 中即我們的 js 裡加入了一個小型的 HMR 執行環境,在編譯過程中這個 runtime 會在我們的 app 中運行。
當建置完成時 webpack 也不會消失反而會持續存在,繼續監控原始碼檔案是否發生修改。一旦 webpack 發現程式有改變他就會去重新編譯那些有修改的模組,不全部重建。根據設定要嘛就是 webpack 把訊號丟給 HRM runtime 要嘛就是 HRM 自己更新異動資訊。不管哪種方式反正重點就是 HRM runtime 會取得修改的模組,接著就試著在運行的狀態下更新模組。首先會先檢查更新的模組是否能 self-accept
。
關於 self-accept
先看看範例和原始碼,意思是要支援熱替換的模組或說編譯結果
基本上是應該要實作 module.hot.accept
和遵循其他熱替換的規則。
如果沒有辦法自己確認自己可以直接被更新,那就往上傳,通知那些 require 匯入使用自己的模組更新,就這樣層層往上。直到有人可以 accept 或到頂,不過一旦到根就表示熱替換失敗。
讀到這邊你可能通了,為什麼當我們要讓 React 支援 Hot Mode 的時候需要一個 react-hot-loader
。以及因為要和 HRM 執行環境溝通的關係我們需要在 bundle 的 entry point 加上 webpack/hot/dev-server
, webpack-hot-middleware/client
之類的東西。
從 App 的角度
當 App 程式開始執行(就是載入 bundle) HMR runtime 執行環境就會啟用,接下來程式就會要求 HMR runtime 幫我們檢查是否需要更新。HMR 會幫我們下載更新然後通知 App 程式有哪些更新可用。
從編譯器(webpack/compiler)的角度
除了一般的資源檔像是圖片,css,編譯器還需要觸發更新事件
讓程式碼可以完成新舊替換。這個"更新"包含兩個部分
更新的 Manifest 支援配置文件(json)
一或多個更新的chunks
程式片段(js)
支援配置文件包含更新後編譯結果的 hash 和新的 chunks 程式碼片段的列表。而新的 chunks 則包含更新後模組的程式碼或 flag
。
編譯器同時也會確保模組和片段 ID 是一致的,透過一個 records
的 json 檔案來儲存相關資訊。
從模組角度
HMR 是選擇性的功能,所以只有在模組包含 HRM 程式碼才會被影響作用。也就是在模組中使用文件有提供的 API。一般來說模組的開發者 handler 會在模組相依的部分更新時被執行。當然也可以寫一個 handler 在這個模組更新時被呼叫。
在大部分的情況並不需要為每一個模組都撰寫支援 HMR 的程式碼
,當一個模組沒有遵循處理規則時就會往上層傳遞事件,意味著只有上方有一個 handler 可以處理就好,但不要讓這個冒泡事件一路冒到頂喔。
從 HMR runtime 角度
模組系統的執行環境其實是額外加入的程式,用來追蹤模組之間的父子關係。
if(module.hot) {
...
}
從管理的角度,這個執行環境 runtime 支援 check
和 apply
兩個方法。
check
的功能是發出 HTTP request 用來取得上面提到的 Manifest,當 request 失敗時就等於沒有任何更新。否則就會依照得到的更新列表
去比對 chunks。
對每個已載入的 chunk 都會有對應更新的程式碼要被下載。所有模組更新會被存在 runtime 中準備拿來更新。當執行環境切換成 ready
狀態就表示更新的程式碼都被下載完成了隨時可以套用。
接著 apply
方法會將所有已更新的模組的 flag
標記為 invalid
無效,然後無效的模組需要 update 的 handler 處理函式,這個 handler 會在模組中或者父節點上。只要沒有這個 handler 就會持續往上曾傳遞並標註為 invalid
,一旦冒泡機制冒到頂端即 entry point
就表示熱替換失敗。
所有被標記為無效的模組都會透過 module.hot.dispose
卸載,然後更新 hash,再來所有 module.hot.accept
的 handlers 會被調用。
執行環境切回 idle
狀態表示所有更新都完成了。
講這麼多其實簡單來說就是我們的模組要補一些 hot mode 的邏輯
var app = require("./app");
// 模擬每 5 秒更新一次
setInterval(function() {
console.log(app(new Date()));
}, 5000);
if(module.hot) {
module.hot.accept("./app", function() {
app = require("./app");
});
}
檔案的更新流程
左邊表示初始化時編譯器產生的結構,右邊則是當模組 4 和 9 更新時的流程。 方塊表示從 Entry 開始,webpack 幫我們編譯產生的部份從 Entry 然後轉換成 Chunk 0 - 4
資源參考
備註
部分內容可能理解不夠精確若有錯誤歡迎指教留言
你可能感兴趣的:(webpack,javascript)
Commander 一款命令行自定义命令依赖
yqcoder
arcgis javascript 前端 node.js
一、安装`commander`插件npminstallcommander二、基本用法1.创建一个简单的命令行程序创建一个JavaScript文件,例如`mycli.js`,并添加以下代码://引入`commander`模块并获取`program`对象。const{program}=require("commander");program .version("1.0.0")//设置命令行工具的版本
【2024年华为OD机试】 (A卷,200分)- 开放日活动、取出尽量少的球(JavaScript&Java & Python&C/C++)
妄北y
算法汇集笔记总结(保姆级) 华为od javascript java c语言 python
一、问题描述题目描述某部门开展FamilyDay开放日活动,其中有个从桶里取球的游戏,游戏规则如下:有N个容量一样的小桶等距排开。每个小桶默认装了数量不等的小球,记录在数组bucketBallNums中。游戏开始时,要求所有桶的小球总数不能超过SUM。如果小球总数超过SUM,则需对所有小桶统一设置一个容量最大值maxCapacity,并将超过容量最大值的小球拿出来,直至小桶里的小球数量小于maxC
Pex 项目使用教程
任翊昆Mary
Pex项目使用教程pexPexisajavascript3dlibrary/engineallowingforseamlessdevelopmentbetweenPlaskandWebGLinthebrowser.项目地址:https://gitcode.com/gh_mirrors/pex/pex1.项目的目录结构及介绍Pex项目的目录结构如下:pex-gl/├──assets/├──lib/├
PEX 开源项目教程
束静研Kody
PEX开源项目教程pexPexisajavascript3dlibrary/engineallowingforseamlessdevelopmentbetweenPlaskandWebGLinthebrowser.项目地址:https://gitcode.com/gh_mirrors/pex/pex项目介绍PEX(PolyethyleneExchange)是一个基于高密度聚乙烯(HDPE)的管道和
学习ASP.NET Core的身份认证(基于JwtBearer的身份认证9)
gc_2299
网页编程 JwtBear 身份认证
测试数据库中只有之前记录温湿度及烟雾值的表中数据较多,在该数据库中增加AppUser表,用于登录用户身份查询,数据库表如下所示: 项目中安装SqlSugarCore包,然后修改控制器类的登录函数及分页查询数据函数,将之前函数中的固定数据修改为从数据库中查询数据,并将分页查询数据函数中返回数据集合修改为返回环境检测数据的集合,主要调整的代码如下所示。客户端页面中的JavaScript代码主要修
谷歌开发者模式调试Js代码 [保姆级教程]
yunAike
javascript 开发语言 ecmascript
开启开发者模式方法一:在网页中右键单击,选择“检查”选项,即可打开开发者工具。方法二:使用快捷键,在Windows/Linux系统中按Ctrl+Shift+I,在Mac系统中按Command+Option+I。开始调试JavaScript代码1.定位到源代码打开开发者工具后,点击上方的“Sources”(源代码)面板。该面板左侧是文件树,你可以从中找到要调试的JavaScript文件。如果是内联的
桌面应用程序开发:跨平台方案方案有什么?
柚米汇
开发语言
目前市面上最流行的桌面开发程序框架和工具包括以下几种:1.Electron简介:使用Web技术(HTML、CSS、JavaScript)开发跨平台桌面应用,结合Node.js和Chromium。优点:广泛使用的Web技术,开发门槛低。丰富的插件和生态系统支持。许多成功的应用案例(如VisualStudioCode、Slack、Discord)。工具:VisualStudioCode、Atom。2.
NPM 常用命令
pumpkin84514
其它 npm
NPM常用命令NPM(NodePackageManager)是JavaScript生态系统中最流行的包管理工具,它不仅可以管理Node.js项目的依赖,还提供了丰富的命令来管理和发布你的代码。本文将从不同角度,深入浅出地介绍NPM的常用命令和实际应用。目录NPM基础什么是NPM安装NPM初始化项目(npminit)管理依赖安装依赖(npminstall)升级和卸载依赖(npmupdate,npmu
【Blazor】使用C#替代Java编写代码的前端开发框架
雕技小虫
系统开发 Windows Server Blazor .NET 前端开发框架 webassembly
Blazor是微软于2019年下半年开始陆续全新推出的前端开发框架。优势无需插件,基于Web标准可与JavaScript交互利用.NETCore优势Blazor有两个版本:Server||WebAssemblyBlazorServer可以理解为在服务器上运行的Blazor,客户端与服务器间通过SignalR实进通信,2019年09月正式发布。BlazorWebAssembly2020年05月正式发
Ajax:万字总结黑马笔记,学懂Ajax看这一篇就够了
做一只猫
前端 ajax javascript 前端
一、了解AjaxAjax的全称是AsynchronousJavascriptAndXML(异步JavaScript和XML)通俗的理解:在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式,就是Ajax如:用户名检测:注册用户时,通过ajax的形式,动态检测用户名是否被占用搜索提示:当输入搜索关键字时,通过ajax的形式,动态加载搜索提示列表数据分页显示:当点击页码值的时候,通过
大侠,你真的了解JS中的toString&toLocaleString方法吗?
不做超级小白
web前端 javascript 前端 开发语言
toString()与toLocaleString()的区别:你需要了解的JavaScript字符串化方法在JavaScript中,toString()和toLocaleString()都是对象转换为字符串的常用方法。虽然它们的功能看似相似,但实际上它们有着不同的用途和行为。本文将详细解析这两者的区别,帮助开发者更好地理解并选择适合的字符串化方法。1.toString()方法:目的:toStrin
TypeScript and Serverless Memory Issue
magic_dreamer
Summary Scripts serverless javascript webpack ViewUI
TypeScriptandServerlessMemoryIssueChangethefiletoaddthefollowcodesatthetop/opt/node/lib/node_modules/serverless/bin/serverless#!/usr/bin/envnode--max-old-space-size=3000--trace-gc-verboseJavaScripthea
Serverless Plugin Optimize 使用指南
舒林艾Natalie
ServerlessPluginOptimize使用指南serverless-plugin-optimize⛔️DEPRECATED⛔️BundlewithBrowserify,transpileandminifywithBabelautomaticallytoyourNodeJSruntimecompatibleJavaScript项目地址:https://gitcode.com/gh_mirr
项目推荐:Serverless优化插件 —— 提升您的云函数性能与效率
井队湛Heath
项目推荐:Serverless优化插件——提升您的云函数性能与效率serverless-plugin-optimize⛔️DEPRECATED⛔️BundlewithBrowserify,transpileandminifywithBabelautomaticallytoyourNodeJSruntimecompatibleJavaScript项目地址:https://gitcode.com/gh
2021年Javascript最常见的面试题以及答案
2401_86401365
javascript 原型模式 开发语言
区别:||和原数据是否指向同一个对象|第一层数据为基本数据类型|原数据中包含的子对象||—|—|—|—||浅拷贝|否|不会使原数据一起改变|会使原数据一起改变||深拷贝|否|不会使原数据一起改变|不会使原数据一起改变|点击对Javscript中浅拷贝和深拷贝的探索和详解查看详解项目中实现深浅拷贝常用的方法有哪些?===========================================
实际开发中的有趣bug:“undefined“ is not valid JSON SyntaxError: “undefined“ is not valid JSON。
我爱加班、、
vue项目实际开发中的bug vuex bug json 前端 javascript vue.js ecmascript ajax
bug解读:指出在尝试解析或序列化JSON数据时遇到了问题。JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它要求数据必须是有效的JSON格式。在JavaScript中,undefined是一个特殊的值,表示变量没有被赋值,它不是一个有效的JSON值。场景:在后台项目,用户登录后,通过用户的菜单权限渲染侧边栏菜单,做了持久化存储。当登出后,在登录页刷新页面,
Java 和 JavaScript 的区别
大乔乔布斯
java javascript 开发语言
尽管名字相似,JavaScript的名字中带有“Java”,确实让很多人误以为它与Java有紧密联系。但实际上,它们是完全不同的语言,只是在JavaScript的发展历史中与Java有一定的关联。1.JavaScript的诞生背景时间点:1995年,网景公司(Netscape)开发了一种轻量级的脚本语言,用于增强网页的交互性。开发者:JavaScript的发明者是布兰登·艾奇(BrendanEic
Vue企业开发实战——学习心得
sienn
vue.js 前端 javascript
一、Vue.js简介Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它与其他大型框架的不同之处在于,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,也便于与第三方库或已有项目整合。二、环境配置安装Node.js和npm:Vue.js的开发需要使用Node.js和npm(Node包管理器)。可以从Node.js的官网下载并安装Node.js,它会自动
vite构建项目中的swc是什么
光影少年
swc react.js vue.js
在Vite项目中,swc是一种高性能的编译器,用于替代传统的JavaScript编译工具,如Babel。它以速度和效率著称,可以加速编译和转换JavaScript和TypeScript代码,从而大幅提升开发和构建的效率。1.什么是swc?swc(SpeedyWebCompiler)是一个用Rust编写的编译器,它能够非常快速地编译、转换和优化JavaScript和TypeScript代码。swc的
前端构建工具
光影少年
前端 软件构建
前端构建工具是开发现代Web应用时不可或缺的工具,用于优化代码、提升开发效率、以及实现高效的构建和部署。以下是常见的前端构建工具及其作用:1.模块打包工具Webpack特点:功能强大,插件与配置灵活。作用:将模块(JS、CSS、图片等)打包成浏览器可运行的文件。适用场景:中大型项目,需高度自定义。Vite特点:轻量、快速构建,基于ESModules。作用:适合现代框架如Vue、React,热更新速
node和nest生态及区别和优势
光影少年
node.js 后端
Node.js与Nest.js的生态与区别及优势1.Node.js生态Node.js是一个基于V8引擎的JavaScript运行时,支持高性能、非阻塞I/O,用于构建服务器端应用程序。生态特点核心模块:提供基础模块(如fs,http,events等),可以直接用于开发。允许构建高性能网络应用,如Web服务器、API服务等。NPM(NodePackageManager):全球最大的包管理器,提供丰富
JavaScript原型链污染漏洞分析
漏洞安全
原型链污染漏洞CVE:1、yargs-Parser输入验证错误漏洞(CVE-2020-7608)2、tough-cookie安全漏洞(CVE-2023-26136)3、JSON5原型污染漏洞(CVE-2022-46175)漏洞描述:1、yargs-Parser输入验证错误漏洞(CVE-2020-7608):yargs-parser是一款选项解析器。yargs-parser13.1.2之前版本、14
JS中window.dispatchEvent的原理和使用初识
匹马夕阳
javascript 前端 开发语言
window.dispatchEvent是JavaScript中用于触发事件的一个方法,它允许开发者在DOM(文档对象模型)中触发特定的事件。这对实现自定义事件或者将事件传递给其他组件或部分的应用非常有用。文章目录使用场景具体代码示例步骤1:创建自定义事件步骤2:触发事件步骤3:监听事件步骤4:集成到页面解释使用场景示例:跨组件通信ModuleA:触发事件ModuleB:监听事件优势注意事项总结使
由于直接展示多种编程语言的全套游戏代码会相当冗长,我将为你概述一个简单的小游戏——猜数字游戏,并用几种流行的编程语言(Python, JavaScript, C++, Java)给出其核心逻辑的代码片
IsaacHornby
游戏 python javascript
Python版本ftinc.cnPython版本非常直观,适合初学者。pythonimportrandomdefguess_number_game():number_to_guess=random.randint(1,100)guess=Noneattempts=0print("我想了一个1到100之间的数字,你能猜到是哪个吗?")whileguess!=number_to_guess:try:g
JavaScript 进阶之路:探索高级特性和最佳实践
不在··
原型模式
面向对象的三大特征封装继承多态构造函数什么是构造函数通过new关键字调用一个函数的时候,这个函数就是构造函数。构造函数和普通函数的区别调用方式不同普通函数只用函数名调用构造函数通过new关键字调用返回值不同普通函数的返回值是函数体内return的结果构造函数的返回值是new关键字生成的对象JSPrototype原型对象所有的函数都有一个原型对象Prototype,并且只有函数才拥有原型对象Prot
Axios 教程:Promise 基础的 HTTP 客户端
吉皎妃Frasier
Axios教程:Promise基础的HTTP客户端axiosaxios/axios:Axios是一个基于Promise的HTTP客户端库,适用于浏览器和Node.js环境,用于在JavaScript应用中执行异步HTTP请求。相较于原生的XMLHttpRequest或FetchAPI,Axios提供了更简洁的API和更强大的功能。项目地址:https://gitcode.com/gh_mirror
[JS]学习笔记2 -- JAVAScript数据类型
Jizhi_Zhang
JavaScript学习笔记 javascript 学习 笔记
一、常量概念:使用const声明的变量称为“常量”。使用场景:当某个变量永远不会改变的时候,就可以使用const来声明,而不是let。命名规范:和变量一致注:常量不允许重新赋值,在声明的时候必须要赋值(初始化)二、数据类型1、基本数据类型1.1数字型number学习中的数字,整数、小数、正数、负数可以有很多操作:算数+:求和-:求差*:求积/:求商%:取模(取余数)--开发中经常作为某个数字是否被
基于 Node.js 的天气查询系统实现(附源码)
Kasper0121
node.js
项目概述这是一个基于Node.js的全栈应用,前端使用原生JavaScript和CSS,后端使用Express框架,通过调用第三方天气API实现天气数据的获取和展示。主要功能默认显示多个主要城市的天气信息支持城市天气搜索响应式布局设计深色主题界面优雅的加载动画技术栈后端:Node.js+Express前端:HTML5+CSS3+JavaScriptHTTP客户端:AxiosAPI:天气API(v1
Three.js学习笔记
癫狂de痴梦
前端 javascript 学习 前端
1.three.js的引入进入官网Three.js–JavaScript3DLibrary,下载文件解压文件,复制three.js-master\build\three.min.js文件在项目中,引入该文件。2.一个简单threeJs程序(1)创建场景constscene=newTHREE.Scene();(2)创建物体constgeomtry=newTHREE.BoxGeometry(1,1,1
Python知识点:基于Python工具和技术,如何使用Truffle进行智能合约开发与部署
杰哥在此
Python系列 python 智能合约 开发语言 编程 面试
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候!如何使用Truffle与Python进行智能合约开发与部署Truffle是一个强大的开发框架,它为以太坊智能合约的开发、测试和部署提供了一整套工具。虽然Truffle主要使用JavaScript和Solidity,但是它也可以与Python工具和技术配合使用,以实现更灵活的开发流程。
Hadoop(一)
朱辉辉33
hadoop linux
今天在诺基亚第一天开始培训大数据,因为之前没接触过Linux,所以这次一起学了,任务量还是蛮大的。
首先下载安装了Xshell软件,然后公司给了账号密码连接上了河南郑州那边的服务器,接下来开始按照给的资料学习,全英文的,头也不讲解,说锻炼我们的学习能力,然后就开始跌跌撞撞的自学。这里写部分已经运行成功的代码吧.
在hdfs下,运行hadoop fs -mkdir /u
maven An error occurred while filtering resources
blackproof
maven 报错
转:http://stackoverflow.com/questions/18145774/eclipse-an-error-occurred-while-filtering-resources
maven报错:
maven An error occurred while filtering resources
Maven -> Update Proje
jdk常用故障排查命令
daysinsun
jvm
linux下常见定位命令:
1、jps 输出Java进程
-q 只输出进程ID的名称,省略主类的名称;
-m 输出进程启动时传递给main函数的参数;
&nb
java 位移运算与乘法运算
周凡杨
java 位移 运算 乘法
对于 JAVA 编程中,适当的采用位移运算,会减少代码的运行时间,提高项目的运行效率。这个可以从一道面试题说起:
问题:
用最有效率的方法算出2 乘以8 等於几?”
答案:2 << 3
由此就引发了我的思考,为什么位移运算会比乘法运算更快呢?其实简单的想想,计算机的内存是用由 0 和 1 组成的二
java中的枚举(enmu)
g21121
java
从jdk1.5开始,java增加了enum(枚举)这个类型,但是大家在平时运用中还是比较少用到枚举的,而且很多人和我一样对枚举一知半解,下面就跟大家一起学习下enmu枚举。先看一个最简单的枚举类型,一个返回类型的枚举:
public enum ResultType {
/**
* 成功
*/
SUCCESS,
/**
* 失败
*/
FAIL,
MQ初级学习
510888780
activemq
1.下载ActiveMQ
去官方网站下载:http://activemq.apache.org/
2.运行ActiveMQ
解压缩apache-activemq-5.9.0-bin.zip到C盘,然后双击apache-activemq-5.9.0-\bin\activemq-admin.bat运行ActiveMQ程序。
启动ActiveMQ以后,登陆:http://localhos
Spring_Transactional_Propagation
布衣凌宇
spring transactional
//事务传播属性
@Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个
@Transactional(propagation=Propagation.NOT_SUPPORTED)//这个方法不开启事务
@Transactional(propagation=Propagation.REQUIREDS_N
我的spring学习笔记12-idref与ref的区别
aijuans
spring
idref用来将容器内其他bean的id传给<constructor-arg>/<property>元素,同时提供错误验证功能。例如:
<bean id ="theTargetBean" class="..." />
<bean id ="theClientBean" class=&quo
Jqplot之折线图
antlove
js jquery Web timeseries jqplot
timeseriesChart.html
<script type="text/javascript" src="jslib/jquery.min.js"></script>
<script type="text/javascript" src="jslib/excanvas.min.js&
JDBC中事务处理应用
百合不是茶
java JDBC编程 事务控制语句
解释事务的概念; 事务控制是sql语句中的核心之一;事务控制的作用就是保证数据的正常执行与异常之后可以恢复
事务常用命令:
Commit提交
[转]ConcurrentHashMap Collections.synchronizedMap和Hashtable讨论
bijian1013
java 多线程 线程安全 HashMap
在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK1.0的一部分。 Hashtable提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的――Hashtable的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。Hashtable的后继者HashMap是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的
ng-if与ng-show、ng-hide指令的区别和注意事项
bijian1013
JavaScript AngularJS
angularJS中的ng-show、ng-hide、ng-if指令都可以用来控制dom元素的显示或隐藏。ng-show和ng-hide根据所给表达式的值来显示或隐藏HTML元素。当赋值给ng-show指令的值为false时元素会被隐藏,值为true时元素会显示。ng-hide功能类似,使用方式相反。元素的显示或
【持久化框架MyBatis3七】MyBatis3定义typeHandler
bit1129
TypeHandler
什么是typeHandler?
typeHandler用于将某个类型的数据映射到表的某一列上,以完成MyBatis列跟某个属性的映射
内置typeHandler
MyBatis内置了很多typeHandler,这写typeHandler通过org.apache.ibatis.type.TypeHandlerRegistry进行注册,比如对于日期型数据的typeHandler,
上传下载文件rz,sz命令
bitcarter
linux命令rz
刚开始使用rz上传和sz下载命令:
因为我们是通过secureCRT终端工具进行使用的所以会有上传下载这样的需求:
我遇到的问题:
sz下载A文件10M左右,没有问题
但是将这个文件A再传到另一天服务器上时就出现传不上去,甚至出现乱码,死掉现象,具体问题
解决方法:
上传命令改为;rz -ybe
下载命令改为:sz -be filename
如果还是有问题:
那就是文
通过ngx-lua来统计nginx上的虚拟主机性能数据
ronin47
ngx-lua 统计 解禁ip
介绍
以前我们为nginx做统计,都是通过对日志的分析来完成.比较麻烦,现在基于ngx_lua插件,开发了实时统计站点状态的脚本,解放生产力.项目主页: https://github.com/skyeydemon/ngx-lua-stats 功能
支持分不同虚拟主机统计, 同一个虚拟主机下可以分不同的location统计.
可以统计与query-times request-time
java-68-把数组排成最小的数。一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的。例如输入数组{32, 321},则输出32132
bylijinnan
java
import java.util.Arrays;
import java.util.Comparator;
public class MinNumFromIntArray {
/**
* Q68输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。
* 例如输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题
Oracle基本操作
ccii
Oracle SQL总结 Oracle SQL语法 Oracle基本操作 Oracle SQL
一、表操作
1. 常用数据类型
NUMBER(p,s):可变长度的数字。p表示整数加小数的最大位数,s为最大小数位数。支持最大精度为38位
NVARCHAR2(size):变长字符串,最大长度为4000字节(以字符数为单位)
VARCHAR2(size):变长字符串,最大长度为4000字节(以字节数为单位)
CHAR(size):定长字符串,最大长度为2000字节,最小为1字节,默认
[强人工智能]实现强人工智能的路线图
comsci
人工智能
1:创建一个用于记录拓扑网络连接的矩阵数据表
2:自动构造或者人工复制一个包含10万个连接(1000*1000)的流程图
3:将这个流程图导入到矩阵数据表中
4:在矩阵的每个有意义的节点中嵌入一段简单的
给Tomcat,Apache配置gzip压缩(HTTP压缩)功能
cwqcwqmax9
apache
背景:
HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML ,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,
SpringMVC and Struts2
dashuaifu
struts2 springMVC
SpringMVC VS Struts2
1:
spring3开发效率高于struts
2:
spring3 mvc可以认为已经100%零配置
3:
struts2是类级别的拦截, 一个类对应一个request上下文,
springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应
所以说从架构本身上 spring3 mvc就容易实现r
windows常用命令行命令
dcj3sjt126com
windows cmd command
在windows系统中,点击开始-运行,可以直接输入命令行,快速打开一些原本需要多次点击图标才能打开的界面,如常用的输入cmd打开dos命令行,输入taskmgr打开任务管理器。此处列出了网上搜集到的一些常用命令。winver 检查windows版本 wmimgmt.msc 打开windows管理体系结构(wmi) wupdmgr windows更新程序 wscrip
再看知名应用背后的第三方开源项目
dcj3sjt126com
ios
知名应用程序的设计和技术一直都是开发者需要学习的,同样这些应用所使用的开源框架也是不可忽视的一部分。此前《
iOS第三方开源库的吐槽和备忘》中作者ibireme列举了国内多款知名应用所使用的开源框架,并对其中一些框架进行了分析,同样国外开发者
@iOSCowboy也在博客中给我们列出了国外多款知名应用使用的开源框架。另外txx's blog中详细介绍了
Facebook Paper使用的第三
Objective-c单例模式的正确写法
jsntghf
单例 ios iPhone
一般情况下,可能我们写的单例模式是这样的:
#import <Foundation/Foundation.h>
@interface Downloader : NSObject
+ (instancetype)sharedDownloader;
@end
#import "Downloader.h"
@implementation
jquery easyui datagrid 加载成功,选中某一行
hae
jquery easyui datagrid 数据加载
1.首先你需要设置datagrid的onLoadSuccess
$(
'#dg'
).datagrid({onLoadSuccess :
function
(data){
$(
'#dg'
).datagrid(
'selectRow'
,3);
}});
2.onL
jQuery用户数字打分评价效果
ini
JavaScript html jquery Web css
效果体验:http://hovertree.com/texiao/jquery/5.htmHTML文件代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery用户数字打分评分代码 - HoverTree</
mybatis的paramType
kerryg
DAO sql
MyBatis传多个参数:
1、采用#{0},#{1}获得参数:
Dao层函数方法:
public User selectUser(String name,String area);
对应的Mapper.xml
<select id="selectUser" result
centos 7安装mysql5.5
MrLee23
centos
首先centos7 已经不支持mysql,因为收费了你懂得,所以内部集成了mariadb,而安装mysql的话会和mariadb的文件冲突,所以需要先卸载掉mariadb,以下为卸载mariadb,安装mysql的步骤。
#列出所有被安装的rpm package rpm -qa | grep mariadb
#卸载
rpm -e mariadb-libs-5.
利用thrift来实现消息群发
qifeifei
thrift
Thrift项目一般用来做内部项目接偶用的,还有能跨不同语言的功能,非常方便,一般前端系统和后台server线上都是3个节点,然后前端通过获取client来访问后台server,那么如果是多太server,就是有一个负载均衡的方法,然后最后访问其中一个节点。那么换个思路,能不能发送给所有节点的server呢,如果能就
实现一个sizeof获取Java对象大小
teasp
java HotSpot 内存 对象大小 sizeof
由于Java的设计者不想让程序员管理和了解内存的使用,我们想要知道一个对象在内存中的大小变得比较困难了。本文提供了可以获取对象的大小的方法,但是由于各个虚拟机在内存使用上可能存在不同,因此该方法不能在各虚拟机上都适用,而是仅在hotspot 32位虚拟机上,或者其它内存管理方式与hotspot 32位虚拟机相同的虚拟机上 适用。
SVN错误及处理
xiangqian0505
SVN提交文件时服务器强行关闭
在SVN服务控制台打开资源库“SVN无法读取current” ---摘自网络 写道 SVN无法读取current修复方法 Can't read file : End of file found
文件:repository/db/txn_current、repository/db/current
其中current记录当前最新版本号,txn_current记录版本库中版本