おいおいおい。。。涙を拭きながら、書き起こしながら、長い間忘れていたインタビューの質問を真冬に思い出さなければなりません。。。
ビュー
vueカスタムディレクティブ
- カスタム命令を通じて Vue の動作を拡張し、DOM 要素をレンダリングするときに機能やイベントを追加し、ビジネス ニーズをより適切に満たすことができます。
- Vue のカスタム命令は、グローバル命令とローカル命令 (コンポーネント内命令) の 2 種類に分けられます。
- グローバル ディレクティブは Vue.directive に登録され、グローバルに使用できますが、ローカル ディレクティブはコンポーネント内でのみ使用できます。
以下はグローバル カスタム ディレクティブの例です。 v-focus という名前のグローバル カスタム ディレクティブを登録します。
v-focus という名前のグローバル カスタム ディレクティブを登録し、ディレクティブがバインドされるときに、挿入されたフック関数を実装します。 要素が DOM に挿入されるとき、要素のフォーカス関数を実現するためにフック関数が呼び出されます。
Vue.directive("focus",{
// 当绑定元素插入到DOM中执行
inserted:function(el){
//聚焦元素
el.focus()
}
})
部分的なカスタム ディレクティブの例を次に示します。 コンポーネント内に v-highlight という名前の部分的なカスタム ディレクティブを定義します。
export default {
derectives:{
highlight:{
//当绑定元素插入到DOM中时执行
inserted:function(el){
//添加样式类
el.classList.add("highlight")
},
//当绑定元素从DOM中移出时执行
unbind:function(el){
//移除样式类
el.classList.remove("highlight")
}
}
}
}
Vue のハッシュ ルーティングとヒストリ ルーティングの違い
hash模式
在hash模式下,路由路径会带有一个#符号
hash模式的路由通过监听 window.location.hash的变化来进行路由切换。
hash模式的好处是兼容性较好,可以在不支持HTML5 History API的浏览器中正常运行
缺点是URL中带有#符号,不够美观
History模式:
在history模式下,路由路径不带有#符号
history模式利用HTML5 HitoryAPI中的pushState和replaceState方法来实现路由切换
history模式的好处是URL更加美观,没有#符号
缺点是兼容性较差,需要在服务器端进行配置,以防止在刷新页面时出现404错误
パーミッションコントロールにおけるカスタム命令の適用
- ユーザーのロール情報に応じて、テーブル内の特定のボタンまたは行と列を表示、編集可能、および削除可能にするかどうかを制御できます。このとき、カスタム コマンドを使用して
このような権限制御を実装できます。 - v-permission という名前のグローバル カスタム コマンドを定義し、バインド フック関数を実装します。この関数では、
現在のユーザーのロール情報を使用して、ユーザーが要素の権限を持っているかどうかを判断します。持っていない場合は、要素を非表示にします。以下はサンプルです
。コード:
//定义一个名为v-permission的全局自定义指令
Vue.directive("permission",{
//bind 钩子函数只在指令第一次绑定到元素时执行一次
//如果需要对指令的绑定值进行响应式的操作,应该在update钩子函数中进行
bind:function(el,binding,vnode){
//获取当前登录用户的角色信息
const currentUser = getUserInfoFromLocalStorage().role;
//获取绑定的值
const {value} = binding
//判断当前用户是否有该按钮的权限
if(value&&value.length&&!value.includes(currentUser)){
el.style.display = "none"; //隐藏该元素
}
}
})
<button v-permission="['admin','superAdmin']">Delete</button>
Vue の動的ルーティング
Vue中的动态路由是指在路由中使用参数来匹配路径的一种方式,通过动态路由,我们可以轻松实现页面参数传递和多个类似页面的复用
{
path:'/user/:id',
name:'user',
component:User
}
:id表示该路由是一个动态路由,所以其被称为参数,它的值会被传递给User组件进行处理
Vueのキーの役割
キーは、ノードを一意に識別するために使用される属性です。
Vue は Dom をレンダリングするときに、ノードのキーが変更されたことを検出したときに、ノードのキーに応じて再レンダリングが必要かどうかを判断します。DOM ツリーからノードを削除し、新しいノードを再作成して適切な位置に挿入します。これにより、DOM 操作の数が減り、レンダリングのパフォーマンスが向上します。
ルータールーティングガード
Router の重要な機能。開発者は、ルートに移動するとき、または現在のルートから離れるときに、いくつかの制御および検証ロジックを実行できます。Vue Router は、グローバル レベル、ルーティング レベル、コンポーネント レベルで次の 3 つの異なるタイプのルーティング ガードを提供します。
- グローバル フロント ガード beforeEach は、ユーザーがログインしているかどうかを確認するために使用され、その他のグローバル コントロールも使用されます。
- グローバル解像度ガード beforeResolve は、グローバル プレガードの後、コンポーネントがレンダリングされる前に呼び出されるように使用されます。
- グローバルの after フック afterEach は、ルートの完了後にクリーンアップするために使用されます。
- ルート専用ガード beforeEnter は、特定のルートに入る前に検証するために使用されます。
-
コンポーネント内のガード beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave は、ページの内部制御ロジックを処理するために使用されます。
JavaScript
イベントループ
イベント ループ (Event Loop) は、非同期タスクを処理するためのメカニズムであり、js ランタイムの一部であり、タスクの実行順序を管理およびスケジュールするために使用されます。
jsでは、タスクは次の2種類に分けられます。
1. 同期タスク:実行が完了するまでコードの順序に従って順番に実行されます
。 2. 非同期タスク:すぐには実行されず、一定の時間に実行されます。将来。非同期タスクには通常、ネットワーク リクエスト、タイマー、イベント リスナーなどが含まれます。
イベント ループは次のように動作します。
1 执行同步任务,直到遇到第一个异步任务。
2 将异步任务放入相应的任务队列(如宏任务队列,微任务队列)中。
3 继续执行后续的同步任务,直到执行栈为空。
4 检查微任务队列,如果有任务则按顺序执行所有的微任务。
5 执行宏任务队列中的一个人物
6.回到第三步,重复以上步骤
各イベント ループでは、最初にすべてのマイクロタスクが実行され、次にマクロタスクが実行されます。このようなメカニズムにより、非同期タスクの実行順序が保証され、ユーザーの操作にタイムリーに応答できます。
一般的なマクロ タスクには setTimeout、setInterval、ネットワーク リクエストなどが含まれ、マイクロ タスクには Promise、MutationObserver などが含まれます。
実際のループを理解することは、効率的な非同期コードを作成するために非常に重要です。これは、タスクを合理的に処理し、メインスレッドのブロックを回避するのに役立ちます。
スコープチェーン:
- js の各関数には独自のスコープがあります。
- 関数内で変数が参照されると、js はコード内に出現する順序で現在のスコープから上方向に検索します。
- この変数を含む最初のスコープが見つかるまで、このプロセスはスコープ チェーン ルックアップと呼ばれます。
- スコープ チェーン全体が見つからない場合は、エラーが報告され、ReferenceError 例外がスローされます。
function outer(){
const a = 10
function inner(){
console.log(a);
console.log(b);//Uncaught: ReferenceError:b is not defined
}
inner()
}
outer()
JSで時刻を変更するときに分と秒が10未満の場合に0を追加するいくつかの方法
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
1 使用ES6模版字符串
padStart指定字符串的长度,如果不满,则在前面补上自己定义的字符串
`${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}`
2 使用三元运算符
(h<10?"0"+h:h)+ ":" + (m<10?"0"+m:m)+":"+(s<10?"0"+s:s)
3 使用Array.map和Array.join方法
const timeArr = [h,m,s].map(value=>{
return value <10?"0"+value:value
})
timeArr.join(":")
ブラウザのアドレスバーに URL を入力するとどうなるか
1. DNS 解決: ブラウザはキャッシュがあるかどうかを確認し、ドメイン名に対応する IP アドレスがあればそれを直接使用します。そうでない場合は、DNS へのリクエストを開始します。 2. Http リクエストを開始し
、ブラウザは URL のプロトコル ヘッダーに従ってサーバーへの応答を開始します 同時に、ブラウザーはいくつかのリクエスト ヘッダーとリクエスト パラメーターも送信します 3. TCP 接続の確立: HTTP リクエストが確立される前に、ブラウザー
はサーバーとの TCP 接続を確立します。TCP は接続指向で信頼性の高い、ワードベースです。スロットル送信プロトコル
により、データの損失や乱れがなく、3 ウェイ ハンドシェイクを通じてデータが正確かつ確実にサーバーに送信されることが保証されます。
4. HTTP リクエストの送信 TCP 接続が確立されると、ブラウザは HTTP リクエスト メッセージを送信できます。サーバーは HTTP リクエスト メッセージを送信します。HTTP 要求メッセージには、要求ヘッダー、要求行、および要求本文が含まれます。
5. サーバーからの応答メッセージを受け入れる: サーバーは要求メッセージを受信すると、要求を解析し、対応する応答メッセージをサーバーに返します。クライアント。HTTP 応答メッセージには、ステータス行、応答ヘッダー、応答本文の 3 つの部分が含まれており、ステータス行にはリクエストの結果ステータス コードが含まれます。
6. ページの解析とレンダリング: ブラウザは、サーバーから返された応答メッセージを受信すると、対応するメッセージの内容 (HTML、CSS、JavaScript など) に従って、対応する DOM ツリー、CSS ルール ツリー、および JavaScript を解析します。およびその他のリソース)をコード化し、
それらからレンダー ツリーを構築します。最後に、これらのコンテンツはブラウザのレンダリング エンジンに渡されてレンダリングされ、最終的に表示されるページが生成されます。
7. TCP 接続を切断します。ブラウザは、サーバーから返された応答メッセージを受信すると、接続を閉じてリソースを解放します。ブラウザがさらにリソースを要求する必要がある場合は、新しい TCP 接続を再確立する必要があります。
リフローと再ペイントを減らす方法
リフローと再描画は、ブラウザのレンダリング プロセスにおける 2 つの重要な手順です。
リフローとは、ブラウザが要素の位置とサイズの属性を計算し、ページを再レイアウトするプロセスを指します。
再描画とは、要素のスタイル属性に従って要素の外観を再描画することを指します。
リフローと再描画はパフォーマンスを消費する操作であるため、リフローと再描画を減らすと、ページのパフォーマンスと応答性が向上します。
1. 批量修改样式:避免对元素的样式属性进行频繁的单独修改,而是尽量将多个样式的修改合并为一个操作。可以使用Css类名的方式一次性地修改多个样式属性。
2. 使用文档片段:如果需要通过js动态地插入一系列元素,可以先将它们添加到文档片段(Document Fragment)中,然后再一次性的讲文档片段添加到文档中,这样可以减少重排的次数。
3. 避免频繁读取布局信息,当获取元素的位置、大小等布局信息时,尽量避免在每次操作中都去读取这些信息,而是将其缓存起来,以减少重排的次数
4. 使用CSS3动画和过渡:CSS3动画和过渡是基于浏览器的硬件加速,可以减少重绘和重排的开销。尽量使用CSS3动画和过渡来实现动画效果,而不是使用js来操作样式属性。
5. 使用requestAnimationFrame: 使用requestAnimationFrame来执行动画可以更好的与浏览器的重绘机制结合,减少不必要的重绘和重排操作
6. 避免频繁的DOM操作:DOM操作会导致重排和重绘,尽量避免频繁的对DOM进行增删改操作,可以先将需要操作的DOM元素从文档中移除,进行批量操作后再重新插入。
7. 使用css布局工具:使用Css的flexBox和Grid等布局工具可以更好地控制页面布局,减少重排的次数。
import と require は、js の 2 つの異なるモジュール化仕様です。
- ES6 の新しいモジュール構文は、インポートの使用法が異なる場合
、他の ES6 モジュールのエクスポートされたオブジェクトをコードに導入するために使用されます。これは、js コードの最外層または他の同様のトップレベルの位置にのみ表示できるトップレベルのステートメントであり、他のコードブロックでは
使用できません。
コードで使用される CommonJS 仕様 CommonJS モジュールのエクスポートされたオブジェクトを導入します。これは、関数内やコード内を含むどこでも使用できます。 const debounce = require("lodash/debounce") - ロードのタイミングが異なり、
コードの編集時にインポートが処理されるため、コードが実行される前に対応するモジュールがロードされています。これにより、コードの実行前に import を静的に分析できるようになり、ビルド時に最適化されます
。 require は実行時にロードされます。つまり、コード内で require が使用されている場合、コードの実行時にモジュールがロードされ、そのエクスポートされたオブジェクトが返されます。結果として -
import の構文は
比較的簡潔で、名前空間の分離とモジュールの分解を実行できます。同時に、モジュールの非同期ロードもサポートします。//引入lodash模块中的debounce方法并重命名为myDebounce //解构 只导出需要的内容,减少导出对象的大小 import {debounce as myDebounce} from "lodash" import * as myModule from "./model.js" //命名空间分离 通过一个对象承载模块的所有导出内容。从而实现命名空间分离 //使用异步函数动态引入模块 const someAsyncModule = await import ('./path/to/module')
require の構文は、特にマルチレイヤー パスのネストが必要な場合に比較的複雑で、名前空間の分離を実行できず、ES6 の構造化構文もサポートしていません。同時に、モジュールを非同期的にロードすることはできないため、追加のライブラリが必要になるか、非同期ロードロジックを手動で作成する必要があります。
つまり、Es6 の新機能を使用する必要がある場合、またはモジュールを非同期でロードする必要がある場合は import を使用し、node または CommonJS 環境と互換性を持たせる必要がある場合は require を使用できます。
WebSocketの使用
WebSocket は、Web ブラウザとサーバー間の全二重通信のためのプロトコルです。より強力なリアルタイム データ送信機能を提供し、従来の HTTP リクエスト/レスポンス モードと比較して、WebSocket ではサーバーがクライアントにデータをアクティブにプッシュできるため、真の双方向通信が実現します。
//创建WebSocket连接 得到一个Websocket对象,url是websocket服务器的地址
const socket = new WebSocket("ws://example.com/socket")
监听事件: WebSocket对象支持多个事件,如`open`,'message',"error"和'close'。通过给WebSocket对象添加对应的事件监听器函数,
可以处理连接打开、接收到消息、出现错误和连接关闭等情况
// 监听连接打开事件
socket.addEventListener("open",event=>{
console.log("WebSocket 连接已打开");
})
// 监听接受到消息事件
socket.addEventListener("message",event=>{
console.log("收到消息",event.data);
})
// 监听连接错误事件
socket.addEventListener("error",error=>{
console.log("WebSocket 错误:",error);
})
//监听连接关闭事件
socket.addEventListener("close",event=>{
console.log("Websocket 连接已关闭");
})
//发送消息 send(data)方法可以向服务器发送消息。服务器接收到消息后,可以通过‘message’ 事件监听器处理。
//客户端可以使用event.data获取服务器发送的消息内容
socket.send("Hello,Websocket")
//关闭连接:当不再需要连接时,可以使用WebSocket对象的close方法来关闭连接
socket.close()
WebSocket 接続にはサーバーのサポートが必要であり、サーバーは接続とメッセージ送信を処理するために対応する WebSocket プロトコルを実装する必要があります。
実際の利用では、Node.jsなどのwsモジュールやWebsocketフレームワークを利用してサーバーサイドの機能を実装できます。
マイクロタスクとマクロタスクと使用シナリオ
マイクロタスクとマクロタスクは、JS 非同期タスクの実行順序を管理するために使用されるメカニズムです。これらは、イベント ループ内でタスクが実行される順序を決定します。
マイクロタスクは、jsエンジンが提供するタスクキューです。マクロタスクよりも実行優先度が高くなります。一般的なマイクロタスクには、Promiseコールバック関数、MutationObserver、progress.nextTickマクロタスクなどがあります。ブラウザが提供するタスクキューです。実行優先度は低く、一般的です
。マクロ タスクには、タイマー setTimeout、setinterval、DOM イベント コールバック、Ajax リクエストなどが含まれます。
使用するシーン:
マイクロタスクを使用するシナリオ:
1. 現在のイベント ループの最後に実行する必要があるタスクについては、Promise のコールバック関数などのマイクロタスクを使用できます。
2 すぐに実行する必要があるタスクの場合は、MutationObserver などのマイクロタスクを使用して DOM の変更を監視し、すぐに応答できます。
マクロ タスクを使用するシナリオ:
1. 遅延する必要があるタスクについては、タイマー コールバック関数などのマクロ タスクを使用できます。
2 イベント サイクルの次のサイクルで実行する必要があるタスクは、DOM 時間コールバックや Ajax リクエストなどのマクロ タスクを使用できます。
イベント ループでは、すべてのマクロ タスクが実行されると、最初にすべてのマイクロ タスクが実行され、次に次のマクロ タスクが実行されます。これにより、マイクロ タスクの優先順位がマクロ タスクの優先順位よりも高くなり、タイムリーな応答が保証されます。まとめると
、マイクロタスクとマクロタスクは非同期タスクの実行順序を管理する仕組みであり、マイクロタスクはマクロタスクよりも実行優先度が高く、すぐに実行する必要があるタスクや終了時に実行するタスクの処理に適しています。現在のループ。マクロタスクは、遅延または次のサイクルで実行する必要があるタスクの処理に適しています。
ES6 のいくつかの一般的な機能と構文
- let および const キーワード
- アロー関数
- 代入の構造化
- スプレッド演算子
- クラスと継承
- テンプレート文字列
- Promise と async/await
- モジュラー
シンボル、マップ、セット、プロキシ、リフレクト
反応する
Vue と React の違い
5 つの側面で:
- テンプレート構文:
Vue は HTML テンプレート構文を使用してコンポーネント テンプレートを作成します。これは比較的理解しやすく学習しやすいため、開発者はページをすばやく作成できます。この利点は、HTML コードと JavaScript コードが分離されており、
コードの保守性と可読性が向上することです。Vue のテンプレート構文は、条件付きレンダリング、ループ レンダリング、イベント処理などのいくつかの強力な機能も提供します。React は、
すべてが JavaScript であり、jsx 構文を使用します。つまり、JavaScript と Xml の混合構文を使用します。jsx を使用すると、簡単に作成できます。複雑な UI をより効率的に処理し、アプリケーションのパフォーマンスを向上させることができます
が、jsx を使用する同僚は、より多くの構文とプログラミング パラダイムを学ぶ必要があります。 - データ バインディング
Vue は、ビューとデータの自動同期を実現できる双方向データ バインディングの機能を提供し、データの管理と運用を大幅に容易にします。双方向バインディングは、データ モデルとビュー モデルの 2 つの部分で構成されます。Vue では、データ モデルはコンポーネント インスタンス内のデータであり、ビュー モデルはデータ モデル内のデータをビューにバインドする役割を果たします。
React のデータフローは一方向であり、コンポーネント間の props と State の転送と管理データを採用し、props を通じてコンポーネントに属性値を渡し、この属性の変更イベントをリッスンして UI を更新することで、データの一方向の流れ
; ステートはコンポーネントの内部状態を保存する場所であり、可変データです。適切な環境下では、可能な限り不変データを使用することをお勧めします。 - コンポーネントの分類
Vue は、コンポーネントを 2 つのタイプに分類します: ステートフル コンポーネントとステートレス機能コンポーネントです。ステートフル コンポーネントには、アプリケーション内のロジックとデータが含まれており、より複雑な操作と対話を実現できます。ステートレス コンポーネントは、データとロジックの処理を行わず、対応する UI インターフェイスのみを提供します。通常、ウィジェットまたは純粋な表示コンポーネントに使用されます。Vue のコンポーネントには、コンポーネントのさまざまな段階でさまざまな処理ロジックを実行できるライフサイクル関数があります。
React には厳密なコンポーネント分類はありませんが、通常、コンポーネントは機能コンポーネントとクラス コンポーネントの 2 つのタイプに分類されます。機能コンポーネントは、パラメータとして props オブジェクトを受け取り、状態関数とライフサイクル関数をサポートしない React 要素を返す純粋な JavaScript 関数です。クラス コンポーネントは、オブジェクト指向プログラミングを使用してコンポーネントを構築し、状態関数とライフサイクル関数をサポートします。 。したがって、React コンポーネントにもライフサイクルがあり、コンポーネントのさまざまな段階で関連する操作を実行できます。
Vue と React はどちらも独自のライフサイクル関数を持ち、これらの関数をさまざまなコンポーネント フェーズで呼び出します。Vue のライフサイクル関数には、create、mounted、update、destroy があり、それぞれの関数には特定の目的と機能がありますが、
React のライフサイクル関数には、componentWillMount、componentDidMount、 shouldComponentUpdate、componentWillUnmount などがあり、これらにも独自の特徴と用途があります。
ライフサイクル関数を使用すると、コンポーネントのマウント、更新、破棄などのプロセスにおける一連の問題とロジックを解決できます。- レンダリング効率
Vue は、仮想 DOM や非同期レンダリングなどのテクノロジを使用して、プログラムのパフォーマンスを向上させます。仮想 DOM は、実際の DOM を js オブジェクトに抽象化し、迅速に比較および計算できるため、DOM 操作によって引き起こされるパフォーマンスの損失を軽減します。非同期レンダリングは可能です
。ブラウザーはアイドル時間中にコンポーネントをレンダリングするため、レンダリング効率が向上します。
React はリコンシリエーションと呼ばれるアルゴリズムを使用して、コンポーネント全体を再レンダリングすることなく UI を更新します。これにより、React のレンダリング効率も高くなります。
コンポーネントが更新されると、React は仮想 DOM の変更を比較して UI を更新し、多数の DOM 操作を回避します。
Vue と React はどちらも優れたフロントエンド フレームワークであり、異なる実装方法を採用し、さまざまな開発シナリオに適しています。Vue は開発経験と使いやすさに重点を置き、中小規模のアプリケーションの迅速な開発に適しています。React はアプリケーションの保守性とパフォーマンスに重点を置き、大規模なアプリケーションやより優れたスケーラビリティを必要とするアプリケーションに適しています。どのフレームワークを選択するかは、プロジェクトのニーズとチームの好みによって異なります。
ウェブパック
webpack-tree-shaking
摇树(tree Shaking)是指在打包过程中,通过静态分析的方式,去掉没有使用的代码,从而减小最终打包后的文件体积
在Webpack中摇树是通过ES6模块化语法和静态分析工具(如UglifyJS)来实现的。
当Webpack打包时,它会分析模块之间的依赖关系,并且检查哪些代码被实际使用了,哪些去除掉没有被使用的代码
摇树的原理是基于ES6模块化的静态特性,它可以在编译时进行静态分析,因为ES6模块化的导入和导出是静态的,而CommonJS模块化的导入和导出是动态的
要实现摇树,需要满足以下条件:
1 使用ES6模块化语法进行导入和导出
2 代码中的导入必须是静态的,不能使用动态导入
3 代码中的导出必须是静态的,不能使用动态导出
当满足这些条件时,Webpack在打包的过程中会自动进行摇树优化,去掉没有使用的代码,从而减小打包后的文件体积
需要注意的是,摇树只能去掉没有使用的代码,而不能去除没有被导入但被使用的代码。
npm run dev のときに webpack は何をしますか
当你运行npm run dev命令时,webpack会执行一系列的操作来构建和打包你的项目。
1. 根据配置文件(通常是webpack.config.js),webpack会读取配置中的入口文件(entry)和出口文件(output)的路径信息。
2. 根据入口文件的路径,webpack会分析项目的依赖关系,找到所有需要打包的模块。
3. webpack会根据配置中的加载器(loader)对模块进行处理。加载器可以将非js文件(如css,图片等)转换为js模块,或者对js模块进行预处理(如使用Babel进行ES6转换)
4. webpack会根据配置中的插件(plugin)对模块进一步的处理。插件可以用于优化打包结果、拓展webpack的功能等。
5. webpack会根据配置中的出口文件路径和文件名,将打包后的模块输出到指定的目录中
6. 在开发模式下,webpack会启动一个开发服务器( dev server),并监听文件的变化,当文件发生变化时,webpack会自动重新构建并刷新浏览器
7 webpack 还会生成一个包含构建信息的统计文件,可以用于分析打包结果、性能优化等
一般的に: webpack が npm run dev を実行すると、構成ファイルに従ってプロジェクトがビルドおよびパッケージ化され、開発サーバーと自動コンパイル機能が提供されます。これは、開発者がリアルタイムでデバッグおよび開発するのに便利です。
Webパックキャッシュ
Webpack は、キャッシュを通じて構築パフォーマンスを向上できるキャッシュ メカニズムを提供します。Webpack のキャッシュ メカニズムには 2 つの側面があります。
-
ローダー キャッシュ:
Webpack ビルド プロセス中に、ローダーはキャッシュを使用してパフォーマンスを向上させることができます。
ローダー キャッシュにより、同じファイルの繰り返し処理が回避され、ビルドが高速化されます。
次のように、cache:true を設定してローダーのキャッシュを有効にします。module:{ rules:[{ test:/\.js$/, use:'babel-loader', options:{ cacheDirectory:true } }] }
- モジュール キャッシュ:
Webpack 構築プロセス中に、Webpack はモジュールのコンテンツに基づいて一意の識別子 (ハッシュ) を生成します。モジュール
内のコンテンツが変更されていない場合、Webpack はモジュールの再構築を避けるために以前のビルド結果を再利用します。ビルド速度を向上させます。
モジュール キャッシュはファイルに基づいており、ファイルの内容が変更された場合にのみ再構築されます。モジュール
キャッシュはデフォルトで有効になっており、cache:true を設定するとキャッシュが有効であることを示すことができます。
ローダー キャッシュとモジュール キャッシュを使用することにより、Webpack は繰り返しの処理を回避し、変更のないモジュールをビルドできるため、ビルドのパフォーマンスと速度が向上します。
キャッシュ メカニズムは、構築プロセス中に見つかったファイルの内容が変更されていない場合にのみ有効になることに注意してください。ファイルの内容が変更された場合、Webpack はモジュール全体と依存関係ツリーを再構築します。
TypeScript
ts に新しい型を追加する方法
ts で新しい型を作成するには、いくつかの方法があります。
1. 类型别名(Type Alias):
使用type 关键字创建一个类型别名,可以给现有类型起一个新的名字
例如: type myType = string|Number;
2.接口(interface):
使用interface 关键字创建一个接口,用于定义一个对象的结构。
例如interface MyInterface{name:string;age:number;}
3.类(Class):
使用class 关键字创建一个类,用于定义一个对象的结构和行为。
例如: class MyClass{name:string;age:number}
4.枚举(Enum):
使用enum关键字创建一个枚举类型,用于定义一组具名的常量值。
例如:enum MyEnum{A,B,C}
任意と不明の違い
Typescript では、any とunknown の両方が不確実な型を表すために使用され、どちらも任意の型を表しますが、それらの間にはいくつかの違いがあります。
1 可赋值性:
any 类型可以赋值给任何类型,也可以从任何类型中获取值
unknown类型只能被赋值给unkown和any类型,不能直接从中获取值。
2 类型检查和类型判断:
any类型的变量不会进行类型检查,编译器不会对其进行类型推断或类型检查。
unknow类型的变量在编译器中会进行类型检查,使用之前必须进行类型检查或类型断言
3 方法和属性的调用:
any类型的变量可以调用任何方法和属性,而不会报错。
unknown类型的变量不能调用任何方法或属性,除非先进行类型断言或类型检查
4 类型安全性:
使用any类型会丧失类型安全性,因为它可以接受任何类型的值。
使用unkonw类型可以提供更好的类型安全性,因为在使用之前必须进行类型检查。
因此,unkown类型相比于any类型提供了更好的类型检查和类型推断,以及更好的类型安全性,因此,尽量使用unkown