Contributing - lekakid/ArcaRefresher GitHub Wiki
κ°λ° νκ²½μ μ€μλ°λλλ€.
νλ‘μ νΈ ν΄λ ꡬ쑰
- component: μ¬λ¬κ³³μμ 곡ν΅μΌλ‘ μ¬μ©λλ μ»΄ν¬λνΈ λͺ¨μ
- core: 리νλ μ ꡬνμ νμν μ€νΈλ§, Redux Store λ± λͺ¨μ
- feature: κ°μ’ κΈ°λ₯ μ»΄ν¬λνΈ λͺ¨μ
- func: ν¨μ λͺ¨μ
- menu: 곡ν΅λ μΈν°νμ΄μ€λ₯Ό μ 곡νκΈ° μν μ»΄ν¬λνΈ λͺ¨μ
- hooks: 리μ‘νΈ μ»€μ€ν ν λͺ¨μ
κΈ°λ₯ ν΄λμ ꡬ쑰
{GroupName}
|-- {FeatureName}
| |-- ArticleMenu.jsx
| |-- ConfigMenu
| | |-- View.jsx
| | `-- index.jsx
| |-- ContextMenu
| | |-- View.jsx
| | `-- index.jsx
| |-- Feature.jsx
| |-- FeatureInfo.jsx
| `-- slice.jsx
|-- {FeatureName}
| |-- ...
κ° κΈ°λ₯ μ»΄ν¬λνΈμ λ©λ΄ ꡬν μ»΄ν¬λνΈλ feature/index.jsx
μ menu/index.jsx
μμ Webpack context κΈ°λ₯μ ν΅ν΄ μλμΌλ‘ ν¬ν¨λ©λλ€.
μ£Όμμ¬ν
/ArticleMenu
,/ConfigMenu
,/ContextMenu
,/Feature
,/slice.jsx
μ μ΄λ¦μ λ°κΏμ μλ©λλ€.- Groupμ΄ μλ‘ λ€λ₯Έ κΈ°λ₯μ΄λλΌλ μ΄λ¦μ΄ κ°μμ μλ©λλ€.
μ€μ λ°μ΄ν°μ κ΄λ¦¬
π‘ redux sliceμ κΈ°λ³Έμ μΈ μμ±λ²μ Redux Toolkit λ¬Έμλ₯Ό μ°Έκ³ λ°λλλ€.
κ° κΈ°λ₯λ€μ μ€μ λ°μ΄ν°λ slice.jsx
μ 리λμ μ μλ₯Ό ν΅ν΄ κ΄λ¦¬λ©λλ€.
defaultStorage
μ€λΈμ νΈλ₯Ό ν΅ν΄ μ μ μ€ν¬λ¦½νΈ νμ₯ νλ‘κ·Έλ¨μ΄ κ΄λ¦¬ν λ°μ΄ν°λ₯Ό μ ν μ μμ΅λλ€.
const defaultStorage = {
myNewConfig: 'hello!',
};
defaultStorage
λ μ΄ν initialState.storage
μ ν λΉν©λλ€.
π« ν λΉνλ μ΄λ¦(storage)μ λ°κΎΈλ©΄ μλ©λλ€.
const initialState = {
storage: getValue(Info.ID, defaultStorage),
// μ΄ μλμ μΈν°νμ΄μ€ μ μ΄μ© state μΆκ°
show: true,
};
storage
λ₯Ό μ μ΄νλ 리λμλ μ΄λ¦μ΄ $
λ‘ μμν΄μΌν©λλ€. $
λ‘ μμνλ 리λμλ₯Ό νΈμΆν λ λ§λ€ μ μ₯ν λ°μ΄ν°μ λ³νκ° μλ€κ³ νλ¨ν©λλ€. μμΈν ꡬ쑰λ core/storage.jsx
μ createMonkeySyncMiddleware
λ₯Ό μ°Έκ³ λ°λλλ€.
export const slice = createSlice({
name: Info.ID,
initialState,
reducers: {
// μλμ κ°μ΄ μΆκ°ν©λλ€.
toggleShow(state) {
state.show = !state.show;
},
// storageλ₯Ό μ μ΄νλ 리λμλ νκ° λκΈ°ν ꡬλΆμ μν΄ μ΄λ¦μ $λ‘ μμν΄μΌν©λλ€!!
$setMyNewConfig(state, action) {
state.storage.myNewConfig = action.payload;
},
},
});
μ€μ λ°μ΄ν°μ μ λ°μ΄νΈ
const defaultStorage = {
version: 1,
contextRange: 'articleItem',
variant: 'badge',
memo: {},
};
function formatUpdater(storage, defaultValue) {
// version 0 => 1
const version = storage?.version || 0;
switch (version) {
case 0: {
const memo = Object.fromEntries(
Object.entries(storage.memo).map(([key, msg]) => [key, { msg }]),
);
const data = getValue('UserColor');
if (data) {
Object.entries(data.color).forEach(([key, color]) => {
(memo[key] ??= {}).color = color;
});
deleteValue('UserColor');
}
const updateStorage = { ...storage };
updateStorage.memo = memo;
updateStorage.version = 1;
return updateStorage;
}
default:
console.warn('μ§μνμ§ μλ λ²μ λ°μ΄ν°μ
λλ€.', storage);
return defaultValue;
}
}
const initialState = {
storage: getValue(Info.ID, defaultStorage, formatUpdater),
};
getValue
μ 3λ²μ§Έ μΈμλ‘ formatUpdater
ν¨μλ₯Ό λ°μ μ μμ΅λλ€. μ μ₯ λ°μ΄ν° λ΄μ version
κ°μ μ§μ νκ³ μ΄ κ°μ λ°λΌ λ°μ΄ν°λ₯Ό νμμ λ°λΌ λ³νν μ μμ΅λλ€. λ³ν μ λ°μ΄ν°λ λ΄λΆ μ μ₯μμ {FeatureName}_v{version}
λ°±μ
λ°μ΄ν°λ‘ λ¨μ΅λλ€.