[{"content":"Bit Twiddling Hacks Summary This note summarizes practical techniques from Bit Twiddling Hacks.\nIt follows the same style as common-algorithm-patterns.md: each topic has Explanation + C++ Framework.\n0) Preconditions and Portability Explanation Bit hacks are highly sensitive to integer representation and shift semantics:\nPrefer unsigned fixed-width types like uint32_t / uint64_t. Right-shifting negative signed values is implementation-defined. Be careful with overflow-prone expressions such as x - y. Code Framework 1 2 3 4 5 6 7 #include \u0026lt;bit\u0026gt; #include \u0026lt;cstdint\u0026gt; #include \u0026lt;limits\u0026gt; using u32 = uint32_t; using u64 = uint64_t; using i32 = int32_t; 1) Sign and Opposite-Sign Detection Explanation Sign extraction is often normalized to -1 / 0 / 1. Two values have opposite signs when their sign bits differ. Code Framework 1 2 3 4 5 6 7 int sign3(int x) { return (x \u0026gt; 0) - (x \u0026lt; 0); // -1 / 0 / 1 } bool oppositeSigns(int x, int y) { return (x ^ y) \u0026lt; 0; } 2) Branchless abs / min / max Explanation Useful when branch misprediction is expensive, but always benchmark against normal standard-library versions first.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 int absNoBranch(int v) { int mask = v \u0026gt;\u0026gt; 31; // implementation-dependent for signed right shift return (v ^ mask) - mask; } int minNoBranch(int x, int y) { return y ^ ((x ^ y) \u0026amp; -(x \u0026lt; y)); } int maxNoBranch(int x, int y) { return x ^ ((x ^ y) \u0026amp; -(x \u0026lt; y)); } 3) Power of Two and Lowbit Explanation x \u0026amp; (x - 1) clears the least significant set bit. A power of two has exactly one set bit. x \u0026amp; -x extracts the lowest set bit. Code Framework 1 2 3 4 5 6 7 8 9 #include \u0026lt;cstdint\u0026gt; bool isPowerOfTwo(uint32_t x) { return x \u0026amp;\u0026amp; ((x \u0026amp; (x - 1)) == 0); } uint32_t lowbit(uint32_t x) { return x \u0026amp; (~x + 1); // same as x \u0026amp; -x } 3.5) XOR Identity Templates (a ^ a = 0) Explanation For many interview problems, these identities are enough:\na ^ a = 0 a ^ 0 = a XOR is associative and commutative Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include \u0026lt;vector\u0026gt; using namespace std; int singleNumber(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { int x = 0; for (int v : nums) x ^= v; return x; } int missingNumber(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { int n = (int)nums.size(); int x = n; for (int i = 0; i \u0026lt; n; ++i) { x ^= i ^ nums[i]; } return x; } 3.6) Ring Indexing via index \u0026amp; (len - 1) Explanation When len is a power of two, index \u0026amp; (len - 1) is equivalent to index % len, often used in ring buffers.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include \u0026lt;cassert\u0026gt; #include \u0026lt;cstdint\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; bool isPow2(size_t n) { return n \u0026amp;\u0026amp; ((n \u0026amp; (n - 1)) == 0); } int circularAt(const vector\u0026lt;int\u0026gt;\u0026amp; arr, int64_t index) { const size_t n = arr.size(); assert(isPow2(n)); size_t pos = static_cast\u0026lt;size_t\u0026gt;(index) \u0026amp; (n - 1); return arr[pos]; } 4) Conditional Bit Set/Clear and Mask Merge Explanation These are common branch-elimination patterns for partial bit updates.\nCode Framework 1 2 3 4 5 6 7 8 9 #include \u0026lt;cstdint\u0026gt; uint32_t setOrClearByFlag(uint32_t w, uint32_t mask, bool flag) { return (w \u0026amp; ~mask) | (static_cast\u0026lt;uint32_t\u0026gt;(-static_cast\u0026lt;int\u0026gt;(flag)) \u0026amp; mask); } uint32_t mergeByMask(uint32_t a, uint32_t b, uint32_t mask) { return (a \u0026amp; ~mask) | (b \u0026amp; mask); } 4.5) Bitmask State Operations Explanation Essential toolbox for state compression and subset DP:\ntest / set / clear / toggle clear lowest set bit Code Framework 1 2 3 4 5 6 7 #include \u0026lt;cstdint\u0026gt; bool testBit(uint32_t x, int k) { return (x \u0026gt;\u0026gt; k) \u0026amp; 1u; } uint32_t setBit(uint32_t x, int k) { return x | (1u \u0026lt;\u0026lt; k); } uint32_t clearBit(uint32_t x, int k) { return x \u0026amp; ~(1u \u0026lt;\u0026lt; k); } uint32_t toggleBit(uint32_t x, int k) { return x ^ (1u \u0026lt;\u0026lt; k); } uint32_t clearLowestOne(uint32_t x) { return x \u0026amp; (x - 1); } 5) Popcount Explanation Kernighan method: loops by number of set bits. std::popcount: preferred C++20 API. Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include \u0026lt;bit\u0026gt; #include \u0026lt;cstdint\u0026gt; int popcountKernighan(uint32_t x) { int cnt = 0; while (x) { x \u0026amp;= (x - 1); ++cnt; } return cnt; } int popcountStd(uint32_t x) { return std::popcount(x); } 6) Parity Explanation Parity is popcount(x) % 2, often reduced via XOR folding.\nCode Framework 1 2 3 4 5 6 7 8 9 10 #include \u0026lt;cstdint\u0026gt; int parity32(uint32_t x) { x ^= x \u0026gt;\u0026gt; 16; x ^= x \u0026gt;\u0026gt; 8; x ^= x \u0026gt;\u0026gt; 4; x ^= x \u0026gt;\u0026gt; 2; x ^= x \u0026gt;\u0026gt; 1; return x \u0026amp; 1; } 7) CTZ and Log2 Explanation CTZ (count trailing zeros) is common in sparse-bit iteration. floor(log2(x)) is the highest set-bit index. Code Framework 1 2 3 4 5 6 7 8 9 10 11 #include \u0026lt;bit\u0026gt; #include \u0026lt;cstdint\u0026gt; int ctz32(uint32_t x) { if (x == 0) return 32; return std::countr_zero(x); } int floorLog2(uint32_t x) { return std::bit_width(x) - 1; // x \u0026gt; 0 } 8) Round Up to Next Power of Two Explanation Classic bit spreading: fill all bits right of MSB, then add one.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 #include \u0026lt;cstdint\u0026gt; uint32_t roundUpPow2(uint32_t x) { if (x \u0026lt;= 1) return 1; --x; x |= x \u0026gt;\u0026gt; 1; x |= x \u0026gt;\u0026gt; 2; x |= x \u0026gt;\u0026gt; 4; x |= x \u0026gt;\u0026gt; 8; x |= x \u0026gt;\u0026gt; 16; return x + 1; } 9) Bit Reverse Explanation Used in FFT and encoding contexts. Simple per-bit loop is portable and clear.\nCode Framework 1 2 3 4 5 6 7 8 9 10 #include \u0026lt;cstdint\u0026gt; uint32_t reverseBits32(uint32_t x) { uint32_t r = 0; for (int i = 0; i \u0026lt; 32; ++i) { r = (r \u0026lt;\u0026lt; 1) | (x \u0026amp; 1u); x \u0026gt;\u0026gt;= 1; } return r; } 10) Zero-Byte Detection in a Word Explanation A classic trick to check if any byte in a word is zero.\nCode Framework 1 2 3 4 5 #include \u0026lt;cstdint\u0026gt; bool hasZeroByte(uint32_t x) { return ((x - 0x01010101u) \u0026amp; ~x \u0026amp; 0x80808080u) != 0; } 11) Mod by 2^s and by (2^s - 1) Explanation % (1 \u0026lt;\u0026lt; s) can be replaced with bitmasking. % (2^s - 1) often uses fold-and-add strategies. Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 #include \u0026lt;cstdint\u0026gt; uint32_t modPow2(uint32_t x, unsigned s) { return x \u0026amp; ((1u \u0026lt;\u0026lt; s) - 1u); } uint32_t modPow2Minus1(uint32_t x, unsigned s) { uint32_t d = (1u \u0026lt;\u0026lt; s) - 1u; while (x \u0026gt; d) { x = (x \u0026amp; d) + (x \u0026gt;\u0026gt; s); } return (x == d) ? 0 : x; } 12) Next Bit Permutation with Same Popcount Explanation Given a bitmask, compute the next larger mask with the same number of set bits.\nCode Framework 1 2 3 4 5 6 7 8 #include \u0026lt;cstdint\u0026gt; uint32_t nextBitPermutation(uint32_t v) { uint32_t c = v \u0026amp; -v; uint32_t r = v + c; if (r == 0) return 0; return (((r ^ v) \u0026gt;\u0026gt; 2) / c) | r; } 13) Practical Guidance Explanation Start with readable baseline code. Prefer C++20 \u0026lt;bit\u0026gt; APIs where possible. Introduce hacks only in measured hotspots. Test edge cases: 0, all-ones, single-bit, INT_MIN. Code Framework 1 // baseline -\u0026gt; profile -\u0026gt; optimize -\u0026gt; benchmark -\u0026gt; keep tests ","permalink":"https://yy-tech.online/post/bit-twiddling-hacks-summary/","summary":"\u003ch1 id=\"bit-twiddling-hacks-summary\"\u003eBit Twiddling Hacks Summary\u003c/h1\u003e\n\u003cp\u003eThis note summarizes practical techniques from \u003ca href=\"https://graphics.stanford.edu/~seander/bithacks.html\"\u003eBit Twiddling Hacks\u003c/a\u003e.\u003cbr\u003e\nIt follows the same style as \u003ccode\u003ecommon-algorithm-patterns.md\u003c/code\u003e: each topic has \u003cstrong\u003eExplanation\u003c/strong\u003e + \u003cstrong\u003eC++ Framework\u003c/strong\u003e.\u003c/p\u003e\n\u003ch2 id=\"0-preconditions-and-portability\"\u003e0) Preconditions and Portability\u003c/h2\u003e\n\u003ch3 id=\"explanation\"\u003eExplanation\u003c/h3\u003e\n\u003cp\u003eBit hacks are highly sensitive to integer representation and shift semantics:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ePrefer unsigned fixed-width types like \u003ccode\u003euint32_t\u003c/code\u003e / \u003ccode\u003euint64_t\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eRight-shifting negative signed values is implementation-defined.\u003c/li\u003e\n\u003cli\u003eBe careful with overflow-prone expressions such as \u003ccode\u003ex - y\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"code-framework\"\u003eCode Framework\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;bit\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstdint\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;limits\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"n\"\u003eu32\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kt\"\u003euint32_t\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"n\"\u003eu64\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kt\"\u003euint64_t\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"n\"\u003ei32\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kt\"\u003eint32_t\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"1-sign-and-opposite-sign-detection\"\u003e1) Sign and Opposite-Sign Detection\u003c/h2\u003e\n\u003ch3 id=\"explanation-1\"\u003eExplanation\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eSign extraction is often normalized to \u003ccode\u003e-1 / 0 / 1\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eTwo values have opposite signs when their sign bits differ.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"code-framework-1\"\u003eCode Framework\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esign3\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// -1 / 0 / 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eoppositeSigns\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ey\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e \u003cspan class=\"o\"\u003e^\u003c/span\u003e \u003cspan class=\"n\"\u003ey\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"2-branchless-abs--min--max\"\u003e2) Branchless abs / min / max\u003c/h2\u003e\n\u003ch3 id=\"explanation-2\"\u003eExplanation\u003c/h3\u003e\n\u003cp\u003eUseful when branch misprediction is expensive, but always benchmark against normal standard-library versions first.\u003c/p\u003e","title":"Bit Twiddling Hacks Summary"},{"content":"Common Algorithm Patterns Each pattern has only two parts: Explanation + Code Framework.\n1) Framework Thinking (Traversal First) Explanation Most problems are traversal problems in disguise: arrays, linked lists, trees, graphs.\nIdentify the data structure first, then pick traversal order, then fill business logic into the skeleton.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include \u0026lt;vector\u0026gt; using namespace std; struct ListNode { int val; ListNode* next; }; struct TreeNode { int val; TreeNode* left; TreeNode* right; }; void processValue(int x) { // TODO: business logic (void)x; } void traverseArray(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { for (int i = 0; i \u0026lt; (int)nums.size(); ++i) { processValue(nums[i]); } } void traverseList(ListNode* head) { for (ListNode* p = head; p != nullptr; p = p-\u0026gt;next) { processValue(p-\u0026gt;val); } } void traverseTree(TreeNode* root) { if (root == nullptr) return; // Pre-order processValue(root-\u0026gt;val); traverseTree(root-\u0026gt;left); traverseTree(root-\u0026gt;right); // Post-order } 2) Binary Search (Shrink Search Space) Explanation Use binary search when monotonicity exists.\nThe key is consistency: interval definition + boundary update rules.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include \u0026lt;vector\u0026gt; using namespace std; int binarySearch(const vector\u0026lt;int\u0026gt;\u0026amp; nums, int target) { int left = 0, right = (int)nums.size() - 1; while (left \u0026lt;= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) return mid; if (nums[mid] \u0026lt; target) { left = mid + 1; } else { right = mid - 1; } } return -1; } int leftBound(const vector\u0026lt;int\u0026gt;\u0026amp; nums, int target) { int left = 0, right = (int)nums.size(); // [left, right) while (left \u0026lt; right) { int mid = left + (right - left) / 2; if (nums[mid] \u0026gt;= target) { right = mid; } else { left = mid + 1; } } if (left \u0026gt;= (int)nums.size() || nums[left] != target) return -1; return left; } 3) BFS (Minimum Steps / Layer Expansion) Explanation BFS explores level by level, so it naturally solves minimum-step problems on unweighted graphs.\nThe main difficulty is usually state modeling, not BFS itself.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include \u0026lt;queue\u0026gt; #include \u0026lt;unordered_set\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; vector\u0026lt;int\u0026gt; neighbors(int state) { // TODO: generate adjacent states return {}; } int bfsMinStep(int start, int target) { queue\u0026lt;int\u0026gt; q; unordered_set\u0026lt;int\u0026gt; visited; q.push(start); visited.insert(start); int step = 0; while (!q.empty()) { int sz = (int)q.size(); for (int i = 0; i \u0026lt; sz; ++i) { int cur = q.front(); q.pop(); if (cur == target) return step; for (int nxt : neighbors(cur)) { if (!visited.count(nxt)) { visited.insert(nxt); q.push(nxt); } } } ++step; } return -1; } 4) Bidirectional BFS Explanation Expand from both start and target. Stop when frontiers meet.\nUsually faster than single-source BFS in large state spaces.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include \u0026lt;unordered_set\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; vector\u0026lt;int\u0026gt; neighbors(int state) { // TODO: generate adjacent states return {}; } int bidirectionalBfs(int start, int target) { if (start == target) return 0; unordered_set\u0026lt;int\u0026gt; front{start}, back{target}, visited{start, target}; int step = 0; while (!front.empty() \u0026amp;\u0026amp; !back.empty()) { if (front.size() \u0026gt; back.size()) swap(front, back); unordered_set\u0026lt;int\u0026gt; nextFront; for (int cur : front) { if (back.count(cur)) return step; for (int nxt : neighbors(cur)) { if (!visited.count(nxt)) { visited.insert(nxt); nextFront.insert(nxt); } } } front = move(nextFront); ++step; } return -1; } 5) Backtracking (Decision Tree Enumeration) Explanation Core cycle: choose -\u0026gt; recurse -\u0026gt; undo.\nBest for permutations/combinations/subsets/constraint search.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include \u0026lt;vector\u0026gt; using namespace std; vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt; result; vector\u0026lt;int\u0026gt; path; vector\u0026lt;int\u0026gt; used; bool isValid(int choice) { // TODO: pruning rule (void)choice; return true; } void backtrack(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { if ((int)path.size() == (int)nums.size()) { result.push_back(path); return; } for (int i = 0; i \u0026lt; (int)nums.size(); ++i) { if (used[i]) continue; if (!isValid(nums[i])) continue; path.push_back(nums[i]); used[i] = 1; backtrack(nums); used[i] = 0; path.pop_back(); } } 6) Partition Backtracking (Element View / Bucket View) Explanation Two common models:\nassign each element to one bucket; fill buckets one by one.\nCombine with pruning (sorting, overflow cutoff, symmetry pruning). Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include \u0026lt;algorithm\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; bool dfsPartition(int i, const vector\u0026lt;int\u0026gt;\u0026amp; nums, vector\u0026lt;int\u0026gt;\u0026amp; bucket, int target) { if (i == (int)nums.size()) { for (int s : bucket) { if (s != target) return false; } return true; } for (int j = 0; j \u0026lt; (int)bucket.size(); ++j) { if (bucket[j] + nums[i] \u0026gt; target) continue; if (j \u0026gt; 0 \u0026amp;\u0026amp; bucket[j] == bucket[j - 1]) continue; bucket[j] += nums[i]; if (dfsPartition(i + 1, nums, bucket, target)) return true; bucket[j] -= nums[i]; } return false; } bool canPartitionKSubsets(vector\u0026lt;int\u0026gt; nums, int k) { int sum = 0; for (int x : nums) sum += x; if (k \u0026lt;= 0 || sum % k != 0) return false; int target = sum / k; sort(nums.rbegin(), nums.rend()); vector\u0026lt;int\u0026gt; bucket(k, 0); return dfsPartition(0, nums, bucket, target); } 7) Sliding Window Explanation Maintain a dynamic window [left, right): expand right to find feasible answers, shrink left to optimize.\nWorks well for contiguous substring/subarray constraints.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include \u0026lt;climits\u0026gt; #include \u0026lt;string\u0026gt; #include \u0026lt;unordered_map\u0026gt; using namespace std; int slidingWindowTemplate(const string\u0026amp; s, const string\u0026amp; t) { unordered_map\u0026lt;char, int\u0026gt; need, window; for (char c : t) need[c]++; int left = 0, right = 0; int valid = 0; int bestLen = INT_MAX; while (right \u0026lt; (int)s.size()) { char c = s[right++]; if (need.count(c)) { window[c]++; if (window[c] == need[c]) valid++; } while (valid == (int)need.size()) { // TODO: update your answer bestLen = min(bestLen, right - left); char d = s[left++]; if (need.count(d)) { if (window[d] == need[d]) valid--; window[d]--; } } } return bestLen == INT_MAX ? -1 : bestLen; } 8) Two Pointers (Fast/Slow and Left/Right) Explanation Fast/slow pointers: same direction, in-place filtering and linked-list tricks. Left/right pointers: opposite direction, pairing/palindrome/reverse style problems. Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include \u0026lt;string\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; bool isValidValue(int x) { // TODO: business condition return x \u0026gt;= 0; } int fastSlowFilter(vector\u0026lt;int\u0026gt;\u0026amp; nums) { int slow = 0; for (int fast = 0; fast \u0026lt; (int)nums.size(); ++fast) { if (isValidValue(nums[fast])) { nums[slow++] = nums[fast]; } } return slow; } bool isPalindrome(const string\u0026amp; s) { int left = 0, right = (int)s.size() - 1; while (left \u0026lt; right) { if (s[left] != s[right]) return false; ++left; --right; } return true; } 9) Prefix Sum Explanation Precompute accumulations once, answer range sum queries in O(1).\nClassic space-for-time optimization.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include \u0026lt;vector\u0026gt; using namespace std; struct PrefixSum1D { vector\u0026lt;long long\u0026gt; pre; explicit PrefixSum1D(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { pre.assign(nums.size() + 1, 0); for (int i = 1; i \u0026lt;= (int)nums.size(); ++i) { pre[i] = pre[i - 1] + nums[i - 1]; } } long long rangeSum(int l, int r) const { // [l, r] return pre[r + 1] - pre[l]; } }; struct PrefixSum2D { vector\u0026lt;vector\u0026lt;long long\u0026gt;\u0026gt; pre; explicit PrefixSum2D(const vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; mat) { int m = (int)mat.size(); int n = m ? (int)mat[0].size() : 0; pre.assign(m + 1, vector\u0026lt;long long\u0026gt;(n + 1, 0)); for (int i = 1; i \u0026lt;= m; ++i) { for (int j = 1; j \u0026lt;= n; ++j) { pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + mat[i - 1][j - 1]; } } } }; 10) Difference Array Explanation Best when range updates are frequent and final array is needed once.\nFor adding val on [l, r], only modify two endpoints in diff.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include \u0026lt;vector\u0026gt; using namespace std; struct Difference { vector\u0026lt;long long\u0026gt; diff; explicit Difference(int n) : diff(n, 0) {} void add(int l, int r, long long val) { diff[l] += val; if (r + 1 \u0026lt; (int)diff.size()) diff[r + 1] -= val; } vector\u0026lt;long long\u0026gt; result() const { vector\u0026lt;long long\u0026gt; nums(diff.size(), 0); if (diff.empty()) return nums; nums[0] = diff[0]; for (int i = 1; i \u0026lt; (int)diff.size(); ++i) { nums[i] = nums[i - 1] + diff[i]; } return nums; } }; 11) Union-Find (Disjoint Set Union) Explanation For dynamic connectivity: union sets and query connectivity.\nTypical optimizations: path compression + union by size/rank.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include \u0026lt;vector\u0026gt; using namespace std; class UnionFind { public: explicit UnionFind(int n) : parent(n), sz(n, 1) { for (int i = 0; i \u0026lt; n; ++i) parent[i] = i; } int find(int x) { while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } return x; } void unite(int a, int b) { int ra = find(a), rb = find(b); if (ra == rb) return; if (sz[ra] \u0026lt; sz[rb]) swap(ra, rb); parent[rb] = ra; sz[ra] += sz[rb]; } bool connected(int a, int b) { return find(a) == find(b); } private: vector\u0026lt;int\u0026gt; parent; vector\u0026lt;int\u0026gt; sz; }; 12) Bit Operations Explanation Great for state compression and parity/frequency tricks.\nCommon identities: n \u0026amp; (n - 1), x ^ x = 0, bit masking.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include \u0026lt;vector\u0026gt; using namespace std; bool isBitOne(int x, int k) { return ((x \u0026gt;\u0026gt; k) \u0026amp; 1) == 1; } int setBit(int x, int k) { return x | (1 \u0026lt;\u0026lt; k); } int clearBit(int x, int k) { return x \u0026amp; ~(1 \u0026lt;\u0026lt; k); } int hammingWeight(unsigned int x) { int cnt = 0; while (x != 0) { x \u0026amp;= (x - 1); ++cnt; } return cnt; } int singleNumber(const vector\u0026lt;int\u0026gt;\u0026amp; nums) { int ans = 0; for (int v : nums) ans ^= v; return ans; } 13) Matrix Traversal \u0026amp; Transform Explanation Two high-frequency patterns:\ngeometric transforms (transpose/reverse) for rotation; boundary contraction (top/bottom/left/right) for spiral traversal. Code Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include \u0026lt;algorithm\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; void rotateClockwise90(vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; matrix) { int n = (int)matrix.size(); for (int i = 0; i \u0026lt; n; ++i) { for (int j = i + 1; j \u0026lt; n; ++j) { swap(matrix[i][j], matrix[j][i]); } } for (auto\u0026amp; row : matrix) { reverse(row.begin(), row.end()); } } vector\u0026lt;int\u0026gt; spiralOrder(const vector\u0026lt;vector\u0026lt;int\u0026gt;\u0026gt;\u0026amp; mat) { vector\u0026lt;int\u0026gt; ans; if (mat.empty() || mat[0].empty()) return ans; int top = 0, bottom = (int)mat.size() - 1; int left = 0, right = (int)mat[0].size() - 1; while (top \u0026lt;= bottom \u0026amp;\u0026amp; left \u0026lt;= right) { for (int j = left; j \u0026lt;= right; ++j) ans.push_back(mat[top][j]); ++top; for (int i = top; i \u0026lt;= bottom; ++i) ans.push_back(mat[i][right]); --right; if (top \u0026lt;= bottom) { for (int j = right; j \u0026gt;= left; --j) ans.push_back(mat[bottom][j]); --bottom; } if (left \u0026lt;= right) { for (int i = bottom; i \u0026gt;= top; --i) ans.push_back(mat[i][left]); ++left; } } return ans; } 14) String Multiplication (Grade-School Simulation) Explanation When integers are too large for built-in numeric types, simulate multiplication digit by digit.\nThe core is index mapping + carry handling.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include \u0026lt;string\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; string multiplyStrings(const string\u0026amp; num1, const string\u0026amp; num2) { if (num1 == \u0026#34;0\u0026#34; || num2 == \u0026#34;0\u0026#34;) return \u0026#34;0\u0026#34;; int m = (int)num1.size(), n = (int)num2.size(); vector\u0026lt;int\u0026gt; res(m + n, 0); for (int i = m - 1; i \u0026gt;= 0; --i) { for (int j = n - 1; j \u0026gt;= 0; --j) { int mul = (num1[i] - \u0026#39;0\u0026#39;) * (num2[j] - \u0026#39;0\u0026#39;); int p1 = i + j, p2 = i + j + 1; int sum = mul + res[p2]; res[p2] = sum % 10; res[p1] += sum / 10; } } string ans; int i = 0; while (i \u0026lt; (int)res.size() \u0026amp;\u0026amp; res[i] == 0) ++i; for (; i \u0026lt; (int)res.size(); ++i) ans.push_back(char(\u0026#39;0\u0026#39; + res[i])); return ans.empty() ? \u0026#34;0\u0026#34; : ans; } 15) Fisher-Yates Shuffle Explanation To make all permutations equally likely, at step i choose random index in [i, n - 1] and swap.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 #include \u0026lt;random\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; void shuffleArray(vector\u0026lt;int\u0026gt;\u0026amp; nums) { static random_device rd; static mt19937 gen(rd()); for (int i = 0; i \u0026lt; (int)nums.size(); ++i) { uniform_int_distribution\u0026lt;int\u0026gt; dist(i, (int)nums.size() - 1); int j = dist(gen); swap(nums[i], nums[j]); } } 16) Monte Carlo Validation Explanation For randomized algorithms, run many trials and inspect frequency distribution.\nNot a formal proof, but very useful for sanity checks.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include \u0026lt;iostream\u0026gt; #include \u0026lt;random\u0026gt; #include \u0026lt;string\u0026gt; #include \u0026lt;unordered_map\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; void shuffleArrayForCheck(vector\u0026lt;int\u0026gt;\u0026amp; nums) { static random_device rd; static mt19937 gen(rd()); for (int i = 0; i \u0026lt; (int)nums.size(); ++i) { uniform_int_distribution\u0026lt;int\u0026gt; dist(i, (int)nums.size() - 1); int j = dist(gen); swap(nums[i], nums[j]); } } string stateKey(const vector\u0026lt;int\u0026gt;\u0026amp; arr) { string key; for (int x : arr) key += to_string(x) + \u0026#34;,\u0026#34;; return key; } void monteCarloCheck(vector\u0026lt;int\u0026gt; arr, int T) { unordered_map\u0026lt;string, int\u0026gt; counter; for (int i = 0; i \u0026lt; T; ++i) { vector\u0026lt;int\u0026gt; tmp = arr; shuffleArrayForCheck(tmp); counter[stateKey(tmp)]++; } // TODO: analyze distribution in counter cout \u0026lt;\u0026lt; \u0026#34;distinct states = \u0026#34; \u0026lt;\u0026lt; counter.size() \u0026lt;\u0026lt; \u0026#34;\\n\u0026#34;; } 17) Pancake Sort (Constructive Recursion) Explanation Move current maximum to front, then to final position, and recurse on remaining prefix.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include \u0026lt;algorithm\u0026gt; #include \u0026lt;vector\u0026gt; using namespace std; void flip(vector\u0026lt;int\u0026gt;\u0026amp; cakes, int i, int j) { while (i \u0026lt; j) swap(cakes[i++], cakes[j--]); } int indexOfMax(const vector\u0026lt;int\u0026gt;\u0026amp; cakes, int n) { int idx = 0; for (int i = 1; i \u0026lt; n; ++i) { if (cakes[i] \u0026gt; cakes[idx]) idx = i; } return idx; } void pancakeSortDfs(vector\u0026lt;int\u0026gt;\u0026amp; cakes, int n, vector\u0026lt;int\u0026gt;\u0026amp; ops) { if (n \u0026lt;= 1) return; int idx = indexOfMax(cakes, n); flip(cakes, 0, idx); ops.push_back(idx + 1); flip(cakes, 0, n - 1); ops.push_back(n); pancakeSortDfs(cakes, n - 1, ops); } 18) Probability Modeling (Sample-Space First) Explanation Avoid intuition traps.\nDefine random process clearly, then define sample space/events, then compute with conditional/total probability.\nCode Framework 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include \u0026lt;vector\u0026gt; using namespace std; struct EventCase { double pCase; double pEventGivenCase; }; double totalProbability(const vector\u0026lt;EventCase\u0026gt;\u0026amp; cases) { double ans = 0.0; for (const auto\u0026amp; c : cases) { ans += c.pCase * c.pEventGivenCase; } return ans; } double conditionalProbability(double pEandC, double pC) { if (pC == 0.0) return 0.0; return pEandC / pC; } ","permalink":"https://yy-tech.online/post/common-algorithm-patterns/","summary":"\u003ch1 id=\"common-algorithm-patterns\"\u003eCommon Algorithm Patterns\u003c/h1\u003e\n\u003cp\u003eEach pattern has only two parts: \u003cstrong\u003eExplanation\u003c/strong\u003e + \u003cstrong\u003eCode Framework\u003c/strong\u003e.\u003c/p\u003e\n\u003ch2 id=\"1-framework-thinking-traversal-first\"\u003e1) Framework Thinking (Traversal First)\u003c/h2\u003e\n\u003ch3 id=\"explanation\"\u003eExplanation\u003c/h3\u003e\n\u003cp\u003eMost problems are traversal problems in disguise: arrays, linked lists, trees, graphs.\u003cbr\u003e\nIdentify the data structure first, then pick traversal order, then fill business logic into the skeleton.\u003c/p\u003e\n\u003ch3 id=\"code-framework\"\u003eCode Framework\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eListNode\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eListNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003enext\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eTreeNode\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eTreeNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eleft\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eTreeNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eright\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eprocessValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// TODO: business logic\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etraverseArray\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003evector\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003enums\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003enums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eprocessValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enums\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etraverseList\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eListNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003ehead\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eListNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ehead\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"k\"\u003enullptr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003enext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eprocessValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etraverseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTreeNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"k\"\u003enullptr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// Pre-order\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eprocessValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etraverseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eleft\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etraverseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eright\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// Post-order\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"2-binary-search-shrink-search-space\"\u003e2) Binary Search (Shrink Search Space)\u003c/h2\u003e\n\u003ch3 id=\"explanation-1\"\u003eExplanation\u003c/h3\u003e\n\u003cp\u003eUse binary search when monotonicity exists.\u003cbr\u003e\nThe key is consistency: interval definition + boundary update rules.\u003c/p\u003e","title":"Common Algorithm Patterns"},{"content":"A basic debounce 1 2 3 4 5 6 7 8 9 10 11 12 const _debounce = (fn, delay, immediate = false) =\u0026gt; { let timer; return (...args) =\u0026gt; { const callNow = immediate \u0026amp;\u0026amp; !timer; clearTimeout(timer); timer = setTimeout(() =\u0026gt; { timer = null; if (!immediate) fn(...args); }, delay); if (callNow) fn(...args); }; }; debounce with promise When debounce fires during mouse drag but the wrapped function calls an API and returns a Promise, you often want only the last call to run. Lodash’s debounce requires func to be a function:\n1 2 3 if (typeof func !== \u0026#39;function\u0026#39;) { throw new TypeError(\u0026#39;Expected a function\u0026#39;); } For async work you need a small variant:\nOnly the last Promise 1 2 3 4 5 6 7 8 9 const debounce_promise_last = (fn, delay) =\u0026gt; { let timer = null; return (...args) =\u0026gt; { clearTimeout(timer); return new Promise((resolve) =\u0026gt; { timer = setTimeout(() =\u0026gt; resolve(fn(...args)), delay); }); }; }; Every call gets a Promise, flushed together 1 2 3 4 5 6 7 8 9 10 11 12 13 function debounce_promise_all(fn, delay = 0) { let timer = null; let resolves = []; return function (...args) { clearTimeout(timer); timer = setTimeout(() =\u0026gt; { const result = fn(...args); resolves.forEach((r) =\u0026gt; r(result)); resolves = []; }, delay); return new Promise((r) =\u0026gt; resolves.push(r)); }; } API calls: throttle, cancel, retry For APIs, throttle is common when you want at most one request per window. Harder cases include cancel and retry (often exponential backoff). With very large promise counts (we once had 1000+), you typically need:\nBatch promises (e.g. 20 per group) Unique IDs per promise / task Per-promise logging (we used Splunk) Cancel semantics Retry with backoff for Ajax Implementation is product-specific; no sample code here.\n","permalink":"https://yy-tech.online/post/debounce-with-promise/","summary":"\u003ch2 id=\"a-basic-debounce\"\u003eA basic debounce\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003e_debounce\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003edelay\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecallNow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eclearTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"nx\"\u003edelay\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallNow\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"debounce-with-promise\"\u003edebounce with promise\u003c/h2\u003e\n\u003cp\u003eWhen debounce fires during mouse drag but the wrapped function calls an API and returns a \u003cstrong\u003ePromise\u003c/strong\u003e, you often want only the \u003cstrong\u003elast\u003c/strong\u003e call to run. Lodash’s \u003ccode\u003edebounce\u003c/code\u003e requires \u003ccode\u003efunc\u003c/code\u003e to be a function:\u003c/p\u003e","title":"[Autodesk] debounce with promise"},{"content":"A Basic debounce 1 2 3 4 5 6 7 8 9 10 11 12 const _debounce = (fn, delay, immediate = false) =\u0026gt; { let timer; return (...args) =\u0026gt; { const callNow = immediate \u0026amp;\u0026amp; !timer; clearTimeout(timer); timer = setTimeout(() =\u0026gt; { timer = null; if (!immediate) fn(...args); }, delay); if (callNow) fn(...args); }; }; debounce with promise If you trigger debounce while dragging the mouse, but the wrapped function calls an API and returns a Promise, you often want to run only the last invocation. How should debounce be written for that?\nLodash’s debounce checks that func is a function:\n1 2 3 if (typeof func !== \u0026#39;function\u0026#39;) { throw new TypeError(\u0026#39;Expected a function\u0026#39;); } For async work you need a small variant. The idea is straightforward:\nOnly the last Promise 1 2 3 4 5 6 7 8 9 10 11 12 const debounce_promise_last = (fn, delay) =\u0026gt; { let timer = null; return (...args) =\u0026gt; { clearTimeout(timer); return new Promise((resolve) =\u0026gt; { timer = setTimeout( () =\u0026gt; resolve(fn(...args)), delay, ); }); }; }; Every call gets a Promise, flushed together after delay 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function debounce_promise_all(fn, delay = 0) { let timer = null; let resolves = []; return function (...args) { clearTimeout(timer); timer = setTimeout(() =\u0026gt; { const result = fn(...args); resolves.forEach((r) =\u0026gt; r(result)); resolves = []; }, delay); return new Promise((r) =\u0026gt; resolves.push(r)); }; } API calls: throttle, cancel, retry For API calls, throttle is also common when you want at most one request per time window.\nMore involved cases include cancel and retry (often with exponential backoff). When the number of promises is very large—for example, we once had 1000+ concurrent promises—you need more structure:\nBatch promises — e.g. 20 per group. Unique IDs — tie each promise to a task id. Logging — per-promise logs for debugging (we sent ours to Splunk). Cancel — whether in-flight work should be aborted. Retry — for Ajax APIs, exponential backoff for retry delays is a good fit. The implementation is tightly coupled to the product; no sample code here.\n","permalink":"https://yy-tech.online/post/frontend-debounce-with-promise/","summary":"\u003ch2 id=\"a-basic-debounce\"\u003eA Basic debounce\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003e_debounce\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003edelay\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecallNow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eclearTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eimmediate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"nx\"\u003edelay\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallNow\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003efn\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"debounce-with-promise\"\u003edebounce with promise\u003c/h2\u003e\n\u003cp\u003eIf you trigger debounce while dragging the mouse, but the wrapped function calls an API and returns a \u003cstrong\u003ePromise\u003c/strong\u003e, you often want to run \u003cstrong\u003eonly the last\u003c/strong\u003e invocation. How should debounce be written for that?\u003c/p\u003e","title":"[Autodesk] debounce with promise"},{"content":" A Flask starter scaffold — I had mostly written small Python scripts before, and this project was a chance to build a proper backend skeleton.\n1. JWT token flow Use short-lived access tokens for better security. Workflow Request access token + refresh token (refresh token in a secure cookie: HttpOnly, Secure, SameSite). Send requests with payload + access token; keep the access token in memory (cleared on logout). When the access token expires, use the refresh cookie to obtain a new access token. Access tokens often live ~1 minute to limit window for MITM abuse. Add a one-way hash over parameters for integrity, ideally including request time. Encrypt sensitive header fields with HMAC; the backend uses HMAC when refreshing tokens. JWTs can be stored in Redis for revocation / allowlists; we aimed for a stateless API for other systems to call, so we did not persist sessions server-side. Implementation notes Set-Cookie is set on the server, not in client JS. Cookies must use HttpOnly, Secure, and SameSite or later requests may not send cookies correctly. Security trade-offs This design improves security for the refresh cookie, but browser extensions can still read cookies in some cases. Going stateless is a deliberate compromise.\n2. Authorization model 3. Client implementation redux-thunk, Redux, React, react-hooks, Konva for unidirectional data flow. redux-thunk is simpler than redux-saga for most async flows. react-hooks reduce boilerplate vs class lifecycle methods. Konva works well with TypeScript for canvas drawing. 4. Database safety (XSS) Prefer SQLAlchemy ORM over raw SQL; if you must use raw SQL, escape and validate inputs to avoid injection/XSS-style issues. Add indexes where needed for query speed. Run EXPLAIN on important queries and optimize. 5. Flask backend basics Logging (daily rotation, two handlers) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 self.logger.setLevel(logging.DEBUG) formatter = logging.Formatter(getattr(config, \u0026#34;LOG_FORMAT\u0026#34;)) timedRotatingFileHandler = handlers.TimedRotatingFileHandler( getattr(config, \u0026#34;LOG_FILENAME\u0026#34;), when=getattr(config, \u0026#34;LOG_WHEN\u0026#34;), interval=getattr(config, \u0026#34;LOG_INTERVAL\u0026#34;), backupCount=getattr(config, \u0026#34;LOG_BACKUP_COUNT\u0026#34;), ) timedRotatingFileHandler.setLevel(logging.INFO) timedRotatingFileHandler.setFormatter(formatter) errorLogHandler = handlers.RotatingFileHandler( getattr(config, \u0026#34;LOG_ROTATE_FILENAME\u0026#34;), maxBytes=getattr(config, \u0026#34;LOG_ROTATE_MAXBYTES\u0026#34;), backupCount=getattr(config, \u0026#34;LOG_ROTATE_BACKUP_COUNT\u0026#34;), ) errorLogHandler.setLevel(logging.ERROR) errorLogHandler.setFormatter(formatter) Other baseline pieces Per-environment configuration CORS response headers and explicit OPTIONS handling (no flask-cors dependency required) Serialize DB rows with a small helper: 1 2 3 4 5 6 7 8 9 from sqlalchemy.inspection import inspect class Serializer(object): def serialize(self): return {c: getattr(self, c) for c in inspect(self).attrs.keys()} @staticmethod def serialize_list(lo): return [m.serialize() for m in lo] Singletons (config, logger, etc.) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import threading lock = threading.Lock() class Singleton(type): _instances = {} # type: ignore def __call__(cls, *args, **kwargs): if cls not in cls._instances: with lock: if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__( *args, **kwargs ) return cls._instances[cls] Sphinx + Postman Docs generated from Markdown sources. Postman collections live alongside docs so the team can import and develop against the API quickly. ","permalink":"https://yy-tech.online/post/flask-with-mysql-2/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA Flask starter scaffold — I had mostly written small Python scripts before, and this project was a chance to build a proper backend skeleton.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"1-jwt-token-flow\"\u003e1. JWT token flow\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eUse \u003cstrong\u003eshort-lived access tokens\u003c/strong\u003e for better security.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"workflow\"\u003eWorkflow\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eRequest \u003cstrong\u003eaccess token + refresh token\u003c/strong\u003e (refresh token in a secure cookie: \u003ccode\u003eHttpOnly\u003c/code\u003e, \u003ccode\u003eSecure\u003c/code\u003e, \u003ccode\u003eSameSite\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003eSend requests with \u003cstrong\u003epayload + access token\u003c/strong\u003e; keep the access token in memory (cleared on logout).\u003c/li\u003e\n\u003cli\u003eWhen the access token expires, use the refresh cookie to obtain a new access token.\u003c/li\u003e\n\u003cli\u003eAccess tokens often live ~1 minute to limit window for MITM abuse.\u003c/li\u003e\n\u003cli\u003eAdd a \u003cstrong\u003eone-way hash\u003c/strong\u003e over parameters for integrity, ideally including request time.\u003c/li\u003e\n\u003cli\u003eEncrypt sensitive header fields with \u003cstrong\u003eHMAC\u003c/strong\u003e; the backend uses HMAC when refreshing tokens.\u003c/li\u003e\n\u003cli\u003eJWTs can be stored in \u003cstrong\u003eRedis\u003c/strong\u003e for revocation / allowlists; we aimed for a \u003cstrong\u003estateless\u003c/strong\u003e API for other systems to call, so we did not persist sessions server-side.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"implementation-notes\"\u003eImplementation notes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eSet-Cookie\u003c/code\u003e is set \u003cstrong\u003eon the server\u003c/strong\u003e, not in client JS.\u003c/li\u003e\n\u003cli\u003eCookies must use \u003ccode\u003eHttpOnly\u003c/code\u003e, \u003ccode\u003eSecure\u003c/code\u003e, and \u003ccode\u003eSameSite\u003c/code\u003e or later requests may not send cookies correctly.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"security-trade-offs\"\u003eSecurity trade-offs\u003c/h3\u003e\n\u003cp\u003eThis design improves security for the refresh cookie, but browser extensions can still read cookies in some cases. Going stateless is a deliberate compromise.\u003c/p\u003e","title":"[GLP] Flask With MySQL (2)"},{"content":" A Flask starter scaffold — I had mostly written small Python scripts before, and this project was a chance to build a proper backend skeleton.\n1. Features we need flask blueprint CORS JSON responses easy debugging health check endpoint logging multiple environments flake8 for static analysis yapf for formatting JWT tokens password hashing MySQL Sphinx docs Postman collections tests XSS mitigation (ORM + escaping) parameter integrity — SHA-1 (mitigate MITM tampering) timestamp validation (replay / DoS-style attacks) ","permalink":"https://yy-tech.online/post/flask-with-mysql-1/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA Flask starter scaffold — I had mostly written small Python scripts before, and this project was a chance to build a proper backend skeleton.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"1-features-we-need\"\u003e1. Features we need\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eflask\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eblueprint\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eCORS\u003c/li\u003e\n\u003cli\u003eJSON responses\u003c/li\u003e\n\u003cli\u003eeasy debugging\u003c/li\u003e\n\u003cli\u003ehealth check endpoint\u003c/li\u003e\n\u003cli\u003elogging\u003c/li\u003e\n\u003cli\u003emultiple environments\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eflake8\u003c/code\u003e for static analysis\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eyapf\u003c/code\u003e for formatting\u003c/li\u003e\n\u003cli\u003eJWT tokens\u003c/li\u003e\n\u003cli\u003epassword hashing\u003c/li\u003e\n\u003cli\u003eMySQL\u003c/li\u003e\n\u003cli\u003eSphinx docs\u003c/li\u003e\n\u003cli\u003ePostman collections\u003c/li\u003e\n\u003cli\u003etests\u003c/li\u003e\n\u003cli\u003eXSS mitigation (ORM + escaping)\u003c/li\u003e\n\u003cli\u003eparameter integrity — SHA-1 (mitigate MITM tampering)\u003c/li\u003e\n\u003cli\u003etimestamp validation (replay / DoS-style attacks)\u003c/li\u003e\n\u003c/ul\u003e","title":"[GLP] Flask With MySQL (1)"},{"content":"A colleague dropped some code on me and asked why applying a semi-transparent mask to images was so slow. Apparently it was written by a \u0026ldquo;strong algorithm engineer\u0026rdquo; from another team. Here it is:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # -*- coding: utf-8 -*- import numpy as np import os import cv2 def put_mask(img_path, output_fold): image = cv2.imread(r\u0026#39;E:\\testdemo.jpg\u0026#39;) bbox1 = [72, 41, 208, 330] bbox2 = [100, 80, 248, 334] zeros1 = np.zeros((image.shape), dtype=np.uint8) zeros2 = np.zeros((image.shape), dtype=np.uint8) zeros_mask1 = cv2.rectangle(zeros1, (bbox1[0], bbox1[1]), (bbox1[2], bbox1[3]), color=(0, 0, 255), thickness=-1) zeros_mask2 = cv2.rectangle(zeros2, (bbox2[0], bbox2[1]), (bbox2[2], bbox2[3]), color=(0, 255, 0), thickness=-1) zeros_mask = np.array((zeros_mask1 + zeros_mask2)) try: alpha = 1 # opacity of the original image beta = 0.5 # opacity of the mask layer gamma = 0 # blend original image with mask mask_img = cv2.addWeighted(image, alpha, zeros_mask, beta, gamma) cv2.imwrite(os.path.join(output_fold, \u0026#39;mask_img.jpg\u0026#39;), mask_img) except: print(\u0026#39;error\u0026#39;) put_mask(img_path=\u0026#39;107.jpg\u0026#39;, output_fold=r\u0026#39;E:\\output\u0026#39;) My first reaction: this is pretty careless. Python is easy to write — that\u0026rsquo;s true — but that doesn\u0026rsquo;t mean anything goes.\nThe problem is obvious: the mask is blown up to the full image size before calling addWeighted. addWeighted is already not the fastest operation; doing it on a full-resolution frame when your mask is tiny makes it much worse. Why not blend only the small bounding-box region and copy it back?\nHere\u0026rsquo;s the fix — this isn\u0026rsquo;t even an algorithm, it\u0026rsquo;s just basic engineering intuition: process fewer pixels.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # -*- coding: utf-8 -*- import cv2 as cv def combine_two_color_images(image1, image2): masklayer, background = image1.copy(), image2.copy() masklayer_height = masklayer.shape[0] masklayer_width = masklayer.shape[1] alpha = 0.5 # blend only the region of interest, not the whole frame blended_portion = cv.addWeighted( masklayer, alpha, background[:masklayer_height, :masklayer_width, :], 1 - alpha, 0, background, ) background[:masklayer_height, :masklayer_width, :] = blended_portion cv.imshow(\u0026#39;composited image\u0026#39;, background) cv.waitKey(10000) The result was dramatically faster — the sluggishness completely disappeared.\nWhy? Our mask is typically 200×200 pixels; the source image is 1960×1080. That\u0026rsquo;s roughly a 50× difference in pixel count per operation. Multiply that by tens of thousands of images processed per hour, and a 50× per-frame inefficiency becomes very significant in aggregate.\nWrite code that respects efficiency. End of rant.\n","permalink":"https://yy-tech.online/post/why-is-it-running-slow/","summary":"\u003cp\u003eA colleague dropped some code on me and asked why applying a semi-transparent mask to images was so slow. Apparently it was written by a \u0026ldquo;strong algorithm engineer\u0026rdquo; from another team. Here it is:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# -*- coding: utf-8 -*-\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eimport\u003c/span\u003e \u003cspan class=\"nn\"\u003enumpy\u003c/span\u003e \u003cspan class=\"k\"\u003eas\u003c/span\u003e \u003cspan class=\"nn\"\u003enp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eimport\u003c/span\u003e \u003cspan class=\"nn\"\u003eos\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eimport\u003c/span\u003e \u003cspan class=\"nn\"\u003ecv2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003eput_mask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eimg_path\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eoutput_fold\u003c/span\u003e\u003cspan class=\"p\"\u003e):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eimage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecv2\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eimread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sa\"\u003er\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;E:\\testdemo.jpg\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebbox1\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e72\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e41\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e208\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e330\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebbox2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e80\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e248\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e334\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ezeros1\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003enp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezeros\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eimage\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eshape\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003edtype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003enp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003euint8\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ezeros2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003enp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezeros\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eimage\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eshape\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003edtype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003enp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003euint8\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ezeros_mask1\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecv2\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erectangle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ezeros1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebbox1\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"n\"\u003ebbox1\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]),\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebbox1\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"n\"\u003ebbox1\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e]),\u003c/span\u003e \u003cspan class=\"n\"\u003ecolor\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e255\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003ethickness\u003c/span\u003e\u003cspan class=\"o\"\u003e=-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ezeros_mask2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecv2\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erectangle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ezeros2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebbox2\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"n\"\u003ebbox2\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]),\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebbox2\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"n\"\u003ebbox2\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e]),\u003c/span\u003e \u003cspan class=\"n\"\u003ecolor\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e255\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003ethickness\u003c/span\u003e\u003cspan class=\"o\"\u003e=-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ezeros_mask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003enp\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ezeros_mask1\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003ezeros_mask2\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ealpha\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e    \u003cspan class=\"c1\"\u003e# opacity of the original image\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ebeta\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mf\"\u003e0.5\u003c/span\u003e   \u003cspan class=\"c1\"\u003e# opacity of the mask layer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003egamma\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# blend original image with mask\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003emask_img\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecv2\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaddWeighted\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eimage\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ealpha\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ezeros_mask\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebeta\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003egamma\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecv2\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eimwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eos\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoutput_fold\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;mask_img.jpg\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003emask_img\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eexcept\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nb\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;error\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eput_mask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eimg_path\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;107.jpg\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eoutput_fold\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sa\"\u003er\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;E:\\output\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eMy first reaction: this is pretty careless. Python is easy to write — that\u0026rsquo;s true — but that doesn\u0026rsquo;t mean anything goes.\u003c/p\u003e","title":"[GLP] Why Is It Running Slow?"},{"content":"What Is a Bloom Filter? A Bloom filter is a space-efficient probabilistic data structure used to test whether an element is a member of a set. When an element is added, it is hashed by K independent hash functions, each mapping the element to a position in a bit array, which is then set to 1.\nTo query membership, the same K positions are checked:\nIf any bit is 0 → the element is definitely not in the set. If all bits are 1 → the element is probably in the set (false positives are possible). The key difference from a single-hash bitmap: using K hash functions spreads the load and significantly reduces collision probability.\nCache Penetration Cache penetration occurs when requests for non-existent keys bypass the cache entirely and hit the database on every call. A Bloom filter is a classic solution: check the filter first, and if the element is definitely absent, return early without touching the database.\nLimitations of Bloom Filters The speed and space efficiency come with two trade-offs:\nFalse positives — An element that was never inserted may still pass the membership check if all K bit positions happen to be set by other elements. One mitigation: maintain a separate whitelist for elements known to produce false positives.\nNo deletion — Setting a bit back to 0 would affect other elements that share that position. If deletion is required, use a Counting Bloom Filter instead, which stores counters rather than single bits.\nHow I Implemented It (Node.js) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 const hashers = (value, times) =\u0026gt; { const hash = crypto.createHash(\u0026#39;sha1\u0026#39;).update(value).digest(); const h1 = hash.readUInt32BE(8); const h2 = hash.readUInt32BE(12); const hashes = []; // Two hash functions are sufficient to implement a Bloom filter // without loss in asymptotic false-positive probability. for (let i = 1; i \u0026lt;= times; i++) { hashes.push(h1 + h2 * i); } return hashes; }; class BloomFilter { constructor({ cache, size = 1000000, errorRate = 0.005 }) { if (cache) { const [mark, m, k, e, bits] = cache; this._m = m; this._k = k; this._e = e; this._bits = new Bits(0, bits); } else { this._m = Math.round((-1 * size * Math.log(errorRate)) / LN2_SQUARE); if (this._m % BYTE_LEN) { this._m += BYTE_LEN - (this._m % BYTE_LEN); } this._k = Math.max(1, Math.round((this._m / size) * Math.LN2)); this._e = errorRate; this._bits = new Bits(); } } add(value) { if (isInteger(value)) { this._bits.set(value); } else { hashers(value, this._k).forEach(_ =\u0026gt; this._bits.set(_ % this._m)); } return this; } has(value) { if (isInteger(value)) { return this._bits.get(value); } return hashers(value, this._k).every(_ =\u0026gt; this._bits.get(_ % this._m)); } } module.exports = BloomFilter; Summary Java\u0026rsquo;s Guava library ships a ready-to-use Bloom filter implementation. The hash function above follows the double-hashing technique described in the referenced paper — only two hash functions are needed to achieve optimal false-positive rates. Reference: Less Hashing, Same Performance — Kirsch \u0026amp; Mitzenmacher (2008)\n","permalink":"https://yy-tech.online/post/play-with-bloomfilter/","summary":"\u003ch2 id=\"what-is-a-bloom-filter\"\u003eWhat Is a Bloom Filter?\u003c/h2\u003e\n\u003cp\u003eA Bloom filter is a space-efficient probabilistic data structure used to test whether an element is a member of a set. When an element is added, it is hashed by \u003cstrong\u003eK independent hash functions\u003c/strong\u003e, each mapping the element to a position in a bit array, which is then set to \u003ccode\u003e1\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eTo query membership, the same K positions are checked:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eIf \u003cstrong\u003eany bit is 0\u003c/strong\u003e → the element is \u003cstrong\u003edefinitely not\u003c/strong\u003e in the set.\u003c/li\u003e\n\u003cli\u003eIf \u003cstrong\u003eall bits are 1\u003c/strong\u003e → the element is \u003cstrong\u003eprobably\u003c/strong\u003e in the set (false positives are possible).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe key difference from a single-hash bitmap: using K hash functions spreads the load and significantly reduces collision probability.\u003c/p\u003e","title":"[Autodesk] Play With Bloom Filter"},{"content":"Two Efficient Methods for Line-by-Line File Processing in Shell Method 1: Using a File Descriptor Redirect stdout to a file descriptor (fd 4), then restore it after processing. This is slightly faster for large files.\n1 2 3 4 5 6 7 8 9 10 11 12 13 function while_read_line_bottom_fd_out { \u0026gt;$OUTFILE exec 4\u0026lt;\u0026amp;1 exec 1\u0026gt;$OUTFILE while read LINE do echo \u0026#34;$LINE\u0026#34; : done \u0026lt; $INFILE exec 1\u0026lt;\u0026amp;4 exec 4\u0026gt;\u0026amp;- } Method 2: Without a File Descriptor Simpler and easier to maintain — appends each line directly to the output file.\n1 2 3 4 5 6 7 8 9 function while_read_line_bottom { \u0026gt;$OUTFILE while read LINE do echo \u0026#34;$LINE\u0026#34; \u0026gt;\u0026gt; $OUTFILE : done \u0026lt; $INFILE } A Simple Deployment Task Goal: Copy a built frontend project to 15 remote servers automatically, without password prompts, and apply per-server configuration changes before copying.\nStep 1 — Install expect (macOS) 1 brew install expect Step 2 — Prepare the Server Config File Raw server info (one field per line) came in this format:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Site1 100001 user1 pass1 type1 type2 Site2 100002 user2 pass type3 type4 # ... 50 more entries We need each server on a single comma-separated line. An Emacs keyboard macro handles this nicely:\n1 2 3 4 5 6 7 # F3 = start recording macro # Ctrl-e = go to end of line # , = insert comma separator # Delete = join next line # F4 = stop / replay macro F3 → Ctrl-e → , → Delete → F4 Result:\n1 2 3 Site1,100001,user1,pass1,type1,type2 Site2,100002,user2,pass,type3,type4 # ... 50 more Step 3 — Deployment Script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #!/bin/sh curtime=$(date +%Y-%m-%d,%H:%M:%S) cat /Users/frank/server.yaml | while read line do IFS=\u0026#39;, \u0026#39; read -r -a serverConfig \u0026lt;\u0026lt;\u0026lt; $line echo \u0026#34;[$curtime] Start To Deploy: ${serverConfig[5]}\u0026#34; # 1. Update API constants with per-server base URL and instrument URL BASE_URL=\u0026#34;${serverConfig[1]}:${serverConfig[8]}\u0026#34; INSTRUMENT_URL=\u0026#34;${serverConfig[1]}:${serverConfig[9]}\u0026#34; # macOS sed requires empty string after -i; on Linux omit the \u0026#34;\u0026#34; sed -i \u0026#34;\u0026#34; \u0026#39;s/BASE_URL:.*,/BASE_URL: \u0026#39;\u0026#34;\\\u0026#34;${BASE_URL}\\\u0026#34;,\u0026#34;\u0026#39;/g\u0026#39; src/services/APIConst.js sed -i \u0026#34;\u0026#34; \u0026#39;s/INSTURMENT_URL:.*,/INSTURMENT_URL: \u0026#39;\u0026#34;\\\u0026#34;${INSTRUMENT_URL}\\\u0026#34;,\u0026#34;\u0026#39;/g\u0026#39; src/services/APIConst.js echo \u0026#34;[$curtime] Deploy ${serverConfig[5]}: Base URL → ${BASE_URL}\u0026#34; echo \u0026#34;[$curtime] Deploy ${serverConfig[5]}: Instrument URL → ${INSTRUMENT_URL}\u0026#34; # 2. Build the frontend echo \u0026#34;[$curtime] Checking node_modules...\u0026#34; NodeModuleDir=\u0026#34;${PWD}/node_modules\u0026#34; if [ -d \u0026#34;$NodeModuleDir\u0026#34; ]; then echo \u0026#34;[$curtime] node_modules found, running build directly\u0026#34; else echo \u0026#34;[$curtime] node_modules missing, running npm install first\u0026#34; npm install \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 fi curtime=$(date +%Y-%m-%d,%H:%M:%S) echo \u0026#34;[$curtime] Build started...\u0026#34; # npm run build \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 echo \u0026#34;[$curtime] Build completed!\u0026#34; ls -la ${PWD}/dist/ # 3. SCP the dist folder to the remote server using expect (no password prompt) username=${serverConfig[3]} host=${serverConfig[1]} pass=${serverConfig[4]} port=${serverConfig[2]} echo \u0026#34;[$curtime] Deploying via scp -P ${port} to ${username}@${host}...\u0026#34; expect_commands=\u0026#34; spawn scp -P ${port} -r ${PWD}/dist ${username}@${host}:/home/${username}/work/webcontent expect \\\u0026#34;password:\\\u0026#34; send \\\u0026#34;${pass}\\r\\\u0026#34; expect eof \u0026#34; expect -c \u0026#34;${expect_commands}\u0026#34; curtime=$(date +%Y-%m-%d,%H:%M:%S) echo \u0026#34;[$curtime] SCP completed.\u0026#34; done Note: Steps such as checking nginx/frp service status and printing a deployment summary can be appended after step 3 as needed.\n","permalink":"https://yy-tech.online/post/play-with-shell/","summary":"\u003ch2 id=\"two-efficient-methods-for-line-by-line-file-processing-in-shell\"\u003eTwo Efficient Methods for Line-by-Line File Processing in Shell\u003c/h2\u003e\n\u003ch3 id=\"method-1-using-a-file-descriptor\"\u003eMethod 1: Using a File Descriptor\u003c/h3\u003e\n\u003cp\u003eRedirect stdout to a file descriptor (fd 4), then restore it after processing. This is slightly faster for large files.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efunction\u003c/span\u003e while_read_line_bottom_fd_out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u0026gt;\u003cspan class=\"nv\"\u003e$OUTFILE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nb\"\u003eexec\u003c/span\u003e 4\u0026lt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nb\"\u003eexec\u003c/span\u003e 1\u0026gt;\u003cspan class=\"nv\"\u003e$OUTFILE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"nb\"\u003eread\u003c/span\u003e LINE\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$LINE\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    :\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003edone\u003c/span\u003e \u0026lt; \u003cspan class=\"nv\"\u003e$INFILE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nb\"\u003eexec\u003c/span\u003e 1\u0026lt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"m\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nb\"\u003eexec\u003c/span\u003e 4\u0026gt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e-\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"method-2-without-a-file-descriptor\"\u003eMethod 2: Without a File Descriptor\u003c/h3\u003e\n\u003cp\u003eSimpler and easier to maintain — appends each line directly to the output file.\u003c/p\u003e","title":"[GLP] Play With Shell"},{"content":"Motivation We wanted to set up a lightweight HTTPS server on an internal company network without purchasing a certificate from a public CA. The solution: build our own private Certificate Authority (CA) and issue a self-signed certificate.\nTLS Handshake Overview The browser connects to https://demowebsite.com. The server returns its certificate (containing the server\u0026rsquo;s public key). The browser verifies the certificate against a trusted CA. The browser generates a random symmetric key K and encrypts it with the server\u0026rsquo;s public key. The server decrypts K using its private key — both sides now share K. All subsequent traffic is encrypted with K. Setting Up a Root CA Best practice: the root CA never signs end-entity certificates directly. Instead it signs an intermediate CA, whose key is used for day-to-day issuance. The root key can then be kept offline.\n1. Prepare the Directory Structure 1 2 3 4 5 6 mkdir -p /root/ca cd /root/ca mkdir certs crl newcerts private chmod 700 private touch index.txt serial echo 1000 \u0026gt; serial Prepare the openssl.cnf configuration file for the root CA.\n2. Generate the Root Key 1 2 3 cd /root/ca openssl genrsa -aes256 -out private/ca.key.pem 4096 chmod 400 private/ca.key.pem 3. Create the Root Certificate 1 2 3 4 5 6 cd /root/ca openssl req -config openssl.cnf \\ -key private/ca.key.pem \\ -new -x509 -days 7300 -sha256 -extensions v3_ca \\ -out certs/ca.cert.pem chmod 444 certs/ca.cert.pem 4. Verify the Root Certificate 1 openssl x509 -noout -text -in certs/ca.cert.pem Setting Up an Intermediate CA 1. Prepare the Directory Structure 1 2 3 4 5 6 mkdir /root/ca/intermediate cd /root/ca/intermediate mkdir certs crl csr newcerts private chmod 700 private touch index.txt serial crlnumber echo 1000 \u0026gt; serial Prepare openssl-intermediate.cnf.\n2. Generate the Intermediate Key and CSR 1 2 3 4 cd /root/ca openssl req -config intermediate/openssl-intermediate.cnf -new -sha256 \\ -key intermediate/private/intermediate.key.pem \\ -out intermediate/csr/intermediate.csr.pem 3. Sign the Intermediate Certificate with the Root CA 1 2 3 4 5 6 cd /root/ca openssl ca -config openssl.cnf -extensions v3_intermediate_ca \\ -days 3650 -notext -md sha256 \\ -in intermediate/csr/intermediate.csr.pem \\ -out intermediate/certs/intermediate.cert.pem chmod 444 intermediate/certs/intermediate.cert.pem 4. Verify the Intermediate Certificate 1 2 3 4 5 6 # Inspect the certificate openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem # Verify it against the root openssl verify -CAfile certs/ca.cert.pem \\ intermediate/certs/intermediate.cert.pem Building the Certificate Chain Clients that trust the root CA also need to verify the intermediate CA. Concatenate both certificates into a chain file:\n1 2 3 cat intermediate/certs/intermediate.cert.pem \\ certs/ca.cert.pem \u0026gt; intermediate/certs/ca-chain.cert.pem chmod 444 intermediate/certs/ca-chain.cert.pem Issuing a Server Certificate 1. Generate the Server Key 1 2 3 4 cd /root/ca openssl genrsa -aes256 \\ -out intermediate/private/www.example.com.key.pem 2048 chmod 400 intermediate/private/www.example.com.key.pem 2. Create a Certificate Signing Request (CSR) 1 2 3 4 cd /root/ca openssl req -config intermediate/openssl.cnf \\ -key intermediate/private/www.example.com.key.pem \\ -new -sha256 -out intermediate/csr/www.example.com.csr.pem 3. Sign the Server Certificate 1 2 3 4 5 6 cd /root/ca openssl ca -config intermediate/openssl.cnf \\ -extensions server_cert -days 375 -notext -md sha256 \\ -in intermediate/csr/www.example.com.csr.pem \\ -out intermediate/certs/www.example.com.cert.pem chmod 444 intermediate/certs/www.example.com.cert.pem 4. Verify the Server Certificate 1 2 3 4 5 6 openssl x509 -noout -text \\ -in intermediate/certs/www.example.com.cert.pem # Verify against the full chain openssl verify -CAfile intermediate/certs/ca-chain.cert.pem \\ intermediate/certs/www.example.com.cert.pem Files to Deploy on the Server 1 2 3 ca-chain.cert.pem www.example.com.key.pem www.example.com.cert.pem Verifying the Certificate 1 2 3 4 5 6 # Show the server\u0026#39;s full certificate chain openssl s_client -connect localhost:443 -prexit -showcerts # Verify the leaf cert is signed by your root CA openssl verify -verbose -x509_strict \\ -CAfile ca-chain.cert.pem localhost.cert.pem Using the Certificate in Code Tornado (Python) HTTPS Server 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # Note: ssl_options must include the certificate chain, not just the leaf cert. import ssl import tornado.httpserver import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write(\u0026#34;Hello, world\u0026#34;) def make_app(): return tornado.web.Application([(r\u0026#34;/\u0026#34;, MainHandler)]) if __name__ == \u0026#34;__main__\u0026#34;: application = make_app() ssl_ctx = ssl.create_default_context( ssl.Purpose.CLIENT_AUTH, cafile=\u0026#34;./ca-chain.cert.pem\u0026#34; ) ssl_ctx.load_cert_chain(\u0026#34;./localhost.cert.pem\u0026#34;, \u0026#34;./localhost.key.pem\u0026#34;) http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_ctx) http_server.listen(443) tornado.ioloop.IOLoop.current().start() Making Requests with a Password-Protected Key (Python) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import requests from urllib3.util.ssl_ import create_urllib3_context from requests.adapters import HTTPAdapter import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) cert_path = \u0026#34;./localhost.cert.pem\u0026#34; private_key_path = \u0026#34;./localhost.key.pem\u0026#34; passphrase_key = \u0026#34;your-key-passphrase\u0026#34; class SSLAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): context = create_urllib3_context() context.load_cert_chain( certfile=cert_path, keyfile=private_key_path, password=passphrase_key ) kwargs[\u0026#39;ssl_context\u0026#39;] = context return super().init_poolmanager(*args, **kwargs) session = requests.Session() session.verify = False # Skip server cert validation for self-signed certs session.mount(\u0026#34;https://\u0026#34;, SSLAdapter()) response = session.post(\u0026#34;https://localhost:20191/inference\u0026#34;) print(response.json()) Testing in a Browser Firefox has a built-in certificate manager — you can import your root CA directly without format conversion. Chrome requires importing the root CA into the OS keychain (Keychain Access on macOS). Result after importing:\nSummary This post covers the core steps for building a private CA and issuing self-signed certificates. Topics not covered here but worth exploring:\nCertificate revocation (CRL / OCSP) Format conversion (PEM ↔ DER ↔ PKCS#12) Choosing the right encryption algorithm Best practice: automate certificate issuance and renewal inside your CI/CD pipeline with scheduled rotation jobs. ","permalink":"https://yy-tech.online/post/https-self-signed-certificate/","summary":"\u003ch2 id=\"motivation\"\u003eMotivation\u003c/h2\u003e\n\u003cp\u003eWe wanted to set up a lightweight HTTPS server on an internal company network without purchasing a certificate from a public CA. The solution: build our own private Certificate Authority (CA) and issue a self-signed certificate.\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"tls-handshake-overview\"\u003eTLS Handshake Overview\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"TLS handshake\" loading=\"lazy\" src=\"/images/ssl.png\"\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eThe browser connects to \u003ccode\u003ehttps://demowebsite.com\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe server returns its certificate (containing the server\u0026rsquo;s public key).\u003c/li\u003e\n\u003cli\u003eThe browser verifies the certificate against a trusted CA.\u003c/li\u003e\n\u003cli\u003eThe browser generates a random symmetric key \u003cstrong\u003eK\u003c/strong\u003e and encrypts it with the server\u0026rsquo;s public key.\u003c/li\u003e\n\u003cli\u003eThe server decrypts \u003cstrong\u003eK\u003c/strong\u003e using its private key — both sides now share \u003cstrong\u003eK\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eAll subsequent traffic is encrypted with \u003cstrong\u003eK\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003ch2 id=\"setting-up-a-root-ca\"\u003eSetting Up a Root CA\u003c/h2\u003e\n\u003cp\u003eBest practice: the root CA \u003cstrong\u003enever signs end-entity certificates directly\u003c/strong\u003e. Instead it signs an intermediate CA, whose key is used for day-to-day issuance. The root key can then be kept offline.\u003c/p\u003e","title":"[GLP] How to Create an HTTPS Self-Signed Certificate"},{"content":"What Is WebAssembly? WebAssembly (Wasm) is a portable, compact, fast-loading binary format for the web. C, C++, Rust, Go, Java, C#, and other toolchains can compile to Wasm and ship it to the browser to complement JavaScript. Real-world uses include large games, Google Earth, Magnum, Blazor, and AutoCAD on the web — this post focuses on our AutoCAD case.\nWhy WebAssembly? Mainly performance. JavaScript struggles with heavy CPU/memory work, drawing, and high concurrency. The platform has added pieces like SharedArrayBuffer, but limits remain. We used Emscripten and asm.js, later Binaryen, for roughly 12–15% overall speedup.\nHow We Use It We compile C++ to Wasm with Emscripten. Main challenges:\nHuge codebase Long startup Desktop vs web differences Sync vs async I/O The main thread cannot block without jank; rewriting is costly and third-party libs may need changes. Web Workers help but blocking calls, message timing, no shared memory, and no semaphore-like sync make communication hard.\nApproaches we considered Emterpreter — bytecode + interpreter for sync-like behavior via saved stack/state and timers. Too slow; hard to identify stack functions; hard to maintain.\nSharedArrayBuffer — fast but manual serialization; Spectre concerns led browsers to disable it in many cases.\nService Worker + sync XHR — simulate blocking with sync XHR; intercept network in a service worker. New SW versions require refresh; version consistency needs background updates; startup waits for SW ready.\nMemory access consistency First: asm.js/Wasm was slow on forced casts (e.g. char* → int*). We standardized on memcpy:\n1 2 3 4 5 int* a = new int; unsigned char b = 1; a = (int*) \u0026amp;b; /* became */ memcpy(a, \u0026amp;b, sizeof(int)); Second: Emscripten function pointers require strict types:\n1 2 3 typedef void (*voidType)(int); int myfun(int a) {} voidType fn = (voidType)myfun; // error After optimization, 82 subprojects improved ~50%; builds dropped from ~90 minutes to ~50.\nExceptions Some exceptions were removed for efficiency.\nSummary Startup flow: UI thread → UI init → service worker init → web worker init (Wasm init, fonts, i18n, etc.) → C++ startup.\nOptimization: Wasm instantiation dominates worker startup — faster instantiation and compiler flags (-O3, smaller code, fewer exceptions) help.\n","permalink":"https://yy-tech.online/post/webassembly-autodesk/","summary":"\u003ch2 id=\"what-is-webassembly\"\u003eWhat Is WebAssembly?\u003c/h2\u003e\n\u003cp\u003eWebAssembly (Wasm) is a portable, compact, fast-loading binary format for the web. C, C++, Rust, Go, Java, C#, and other toolchains can compile to Wasm and ship it to the browser to complement JavaScript. Real-world uses include large games, Google Earth, Magnum, Blazor, and \u003cstrong\u003eAutoCAD on the web\u003c/strong\u003e — this post focuses on our AutoCAD case.\u003c/p\u003e\n\u003ch2 id=\"why-webassembly\"\u003eWhy WebAssembly?\u003c/h2\u003e\n\u003cp\u003eMainly \u003cstrong\u003eperformance\u003c/strong\u003e. JavaScript struggles with heavy CPU/memory work, drawing, and high concurrency. The platform has added pieces like \u003ccode\u003eSharedArrayBuffer\u003c/code\u003e, but limits remain. We used Emscripten and asm.js, later \u003cstrong\u003eBinaryen\u003c/strong\u003e, for roughly \u003cstrong\u003e12–15%\u003c/strong\u003e overall speedup.\u003c/p\u003e","title":"[Autodesk] How Autodesk Uses WebAssembly"},{"content":"Slides Team sharing deck Container building blocks namespace Linux control groups (cgroups) UnionFS veth What a container should provide Filesystem isolation — e.g. chroot to change the root mount Network isolation — for distributed apps: own IP, ports, routes; veth pairs so each container has its own netdev, IP, routing table, /proc/net, ports. Multiple containers on one host can each bind port 80 inside their own network namespace Hostname — UTS namespace for identity on the network IPC — separate System V IPC and POSIX message queues; only processes in the same IPC namespace can talk to each other User IDs — in a user namespace, UID/GID can differ from the host; an unprivileged host user can be “root” inside the container Main pieces Piece Details namespace UTS, IPC, PID, NETWORK, MOUNT, USER cgroup CPU, memory, blkio, devices, … UnionFS aufs (Ubuntu), btrfs (SUSE), vfs, devicemapper (CentOS), overlay2 (CentOS/Ubuntu) veth Docker network modes: bridge, host, container, none How containers are implemented A container is essentially a special process created with clone(2):\n1 int clone(int (*fn)(void*), void *child_stack, int flags, void *arg); (fork and clone both go through sys_clone on Linux; the note below is simplified.)\nfork — child continues after the call site clone — child starts at fn(args); parent and child have separate memory views but may share pages; child_stack points at the child stack flags — low bits can carry a signal; Docker-related flags map namespaces: CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWPID, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWUSER cgroup — resource limits under /sys/fs/cgroup\nUnionFS / overlay2 — layer metadata example:\n1 sudo ls /var/lib/docker/image/overlay2/layerdb/${id} veth — virtual Ethernet pair connecting container to the host bridge\n","permalink":"https://yy-tech.online/post/docker-container-study/","summary":"\u003ch2 id=\"slides\"\u003eSlides\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/images/tom.key\"\u003e\u003cstrong\u003eTeam sharing deck\u003c/strong\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"container-building-blocks\"\u003eContainer building blocks\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003enamespace\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eLinux \u003cstrong\u003econtrol groups\u003c/strong\u003e (cgroups)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eUnionFS\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eveth\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"what-a-container-should-provide\"\u003eWhat a container should provide\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eFilesystem isolation\u003c/strong\u003e — e.g. \u003ccode\u003echroot\u003c/code\u003e to change the root mount\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eNetwork isolation\u003c/strong\u003e — for distributed apps: own IP, ports, routes; \u003cstrong\u003eveth\u003c/strong\u003e pairs so each container has its own netdev, IP, routing table, \u003ccode\u003e/proc/net\u003c/code\u003e, ports. Multiple containers on one host can each bind port 80 inside their own network namespace\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHostname\u003c/strong\u003e — UTS namespace for identity on the network\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eIPC\u003c/strong\u003e — separate System V IPC and POSIX message queues; only processes in the same IPC namespace can talk to each other\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eUser IDs\u003c/strong\u003e — in a user namespace, UID/GID can differ from the host; an unprivileged host user can be “root” inside the container\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"main-pieces\"\u003eMain pieces\u003c/h3\u003e\n\u003ctable\u003e\n\t\u003cthead\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003cth\u003ePiece\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003eDetails\u003c/th\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/thead\u003e\n\t\u003ctbody\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003cstrong\u003enamespace\u003c/strong\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003eUTS, IPC, PID, NETWORK, MOUNT, USER\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003cstrong\u003ecgroup\u003c/strong\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003eCPU, memory, blkio, devices, …\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003cstrong\u003eUnionFS\u003c/strong\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003eaufs (Ubuntu), btrfs (SUSE), vfs, devicemapper (CentOS), \u003cstrong\u003eoverlay2\u003c/strong\u003e (CentOS/Ubuntu)\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003cstrong\u003eveth\u003c/strong\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003eDocker network modes: bridge, host, container, none\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"how-containers-are-implemented\"\u003eHow containers are implemented\u003c/h3\u003e\n\u003cp\u003eA container is essentially a \u003cstrong\u003especial process\u003c/strong\u003e created with \u003ccode\u003eclone(2)\u003c/code\u003e:\u003c/p\u003e","title":"[Docker] Container Internals"},{"content":" This is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch. It shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling. It also covers project essentials such as .gitignore, code formatting, per-environment configuration, hot reload, debugging setup, and similar topics.\nHow React Interacts With Middleware Functional programming ideas Curried functions defer execution. Middleware built by repeated currying accumulates arguments; with compose, you get a pipeline-style data flow. Because of closures, after applyMiddleware finishes, every middleware sees the latest store. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 export default function applyMiddleware(...middlewares) { return (createStore) =\u0026gt; (...args) =\u0026gt; { const store = createStore(...args) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) =\u0026gt; dispatch(...args) } // Basically build an array of middleware runner functions and invoke each one chain = middlewares.map(middleware =\u0026gt; middleware(middlewareAPI)) // Enhance dispatch by running it through the middleware chain // This example uses compose to run middleware in sequence dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } How it works Reading the source, applyMiddleware is essentially curry + compose to enhance dispatch. Quick review of curry and compose:\nImplement addition 1 const add=(...args)=\u0026gt;args.reduce((res, cur) =\u0026gt; { return res + cur; }, 0) Now we have one function; add another:\n1 const mul2 = cur =\u0026gt; cur * 2 To mirror applyMiddleware, we have a store—it can be more complex; here it is a simple array:\n1 const store=[1,2,3] We need compose to chain functions (any number of them). The desired shape:\n1 (f1, f2, f3, f4…) =\u0026gt; value =\u0026gt; f1(f2(f3(f4(value)))); A minimal compose:\n1 const compose = (...fns) =\u0026gt; fns.reduceRight((f, g) =\u0026gt; (...args) =\u0026gt; f(g(...args))) Currying shows up in connect too, but here is a simple implementation:\n1 2 3 4 const curry = (fn,...arg1)=\u0026gt;{ if(arg1.length\u0026gt;=fn.length) return fn(...arg1) return (...arg2)=\u0026gt;curry(fn,...arg1,...arg2) } ","permalink":"https://yy-tech.online/post/react-with-webpack-8/","summary":"\u003cblockquote\u003e\n\u003cp\u003eThis is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch.\nIt shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling.\nIt also covers project essentials such as \u003ccode\u003e.gitignore\u003c/code\u003e, code formatting, per-environment configuration,\nhot reload, debugging setup, and similar topics.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"how-react-interacts-with-middleware\"\u003eHow React Interacts With Middleware\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eFunctional programming ideas\nCurried functions defer execution. Middleware built by repeated currying accumulates arguments; with \u003ccode\u003ecompose\u003c/code\u003e, you get a pipeline-style data flow.\u003c/li\u003e\n\u003cli\u003eBecause of closures, after \u003ccode\u003eapplyMiddleware\u003c/code\u003e finishes, every middleware sees the latest \u003ccode\u003estore\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eapplyMiddleware\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddlewares\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecreateStore\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003estore\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ecreateStore\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003estore\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003echain\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003emiddlewareAPI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"nx\"\u003egetState\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003estore\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetState\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"c1\"\u003e// Basically build an array of middleware runner functions and invoke each one\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"nx\"\u003echain\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003emiddlewares\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddlewareAPI\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"c1\"\u003e// Enhance dispatch by running it through the middleware chain\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"c1\"\u003e// This example uses compose to run middleware in sequence\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ecompose\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\u003cspan class=\"nx\"\u003echain\u003c/span\u003e\u003cspan class=\"p\"\u003e)(\u003c/span\u003e\u003cspan class=\"nx\"\u003estore\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"p\"\u003e...\u003c/span\u003e\u003cspan class=\"nx\"\u003estore\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"nx\"\u003edispatch\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"how-it-works\"\u003eHow it works\u003c/h2\u003e\n\u003cp\u003eReading the source, \u003ccode\u003eapplyMiddleware\u003c/code\u003e is essentially curry + compose to enhance \u003ccode\u003edispatch\u003c/code\u003e. Quick review of curry and compose:\u003c/p\u003e","title":"React With Webpack (8)"},{"content":" This is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch. It shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling. It also covers project essentials such as .gitignore, code formatting, per-environment configuration, hot reload, debugging setup, and similar topics.\nWebpack 4: Images and Fonts Code https://github.com/hyyfrank/webpack4 branch: feature/lesson7\nPreparation What we need to do\nSupport jpeg, jpg, gif, png, and similar formats\nCombine images into sprites\nCompress images\nHow to load and handle fonts\nLoaders and plugins we need\nloaders:\nfile-loader: resolves import / require() in files into URLs and emits files to the output directory\nurl-loader: like file-loader, but returns a Data URL when the file is below a size limit (in bytes)\nimg-loader: minimizes images; depends on imagemin; usually used with the loaders above for compression\nsvg-url-loader: SVG is XML text; base64 is not required. UTF-8 encoding can be shorter, compresses better with gzip, and browsers parse UTF-8 faster than base64\nStep 1: Add image handling 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { test: /\\.(jpe?g|png|gif)$/i, use:[ { loader: \u0026#34;url-loader\u0026#34;, options:{ name: \u0026#34;[name]-[hash:5].min.[ext]\u0026#34;, limit: 10000, // size \u0026lt;= 20KB publicPath: \u0026#34;images/\u0026#34;, outputPath: \u0026#34;images/\u0026#34; } }, ] } Step 2: Image compression Each format has its own plugin; install them with npm. See each project on GitHub for options—worth reading if you care about image optimization.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 { test: /\\.(jpe?g|png|gif)$/i, use:[ { loader: \u0026#34;url-loader\u0026#34;, options:{ name: \u0026#34;[name]-[hash:5].min.[ext]\u0026#34;, limit: 10000, // size \u0026lt;= 20KB publicPath: \u0026#34;images/\u0026#34;, outputPath: \u0026#34;images/\u0026#34; } }, ] } Run npm run dev and compare image sizes before and after compression—they should be smaller.\nStep 3: Generate sprites 1 2 3 4 5 6 7 8 9 10 11 12 { loader:\u0026#39;postcss-loader\u0026#39;, options: { sourceMap: true, config: { path: __dirname + \u0026#39;/postcss.config.js\u0026#39; }, plugins: [require(\u0026#34;postcss-sprites\u0026#34;)({ spritePath: \u0026#34;./dist/images\u0026#34; })] }, }, This plugin builds the sprite sheet. Example result:\nStep 4: Font handling Download a font from Google Fonts (or elsewhere if you cannot reach it), convert it with an online font converter, and you get ttf, otf, eot, woff, and other formats locally. Then parse fonts with: 1 2 3 4 5 6 7 8 9 10 11 12 13 { test: /.(ttf|otf|eot|svg|woff(2)?)(\\?[a-z0-9]+)?$/, exclude: /images/, /* dont want svg images from image folder to be included */ use: [ { loader: \u0026#39;file-loader\u0026#39;, options: { outputPath: \u0026#39;fonts/\u0026#39;, name: \u0026#39;[name][hash].[ext]\u0026#39;, }, }, ], } After that, you can reference your fonts in CSS with a custom name:\n1 2 3 4 @font-face { font-family: \u0026#34;frankfont\u0026#34;; src: url(\u0026#34;../fonts/RobotoCondensed-Regular.woff2\u0026#34;) format(\u0026#34;woff2\u0026#34;), url(\u0026#34;../fonts/RobotoCondensed-Regular.woff\u0026#34;) format(\u0026#34;woff\u0026#34;); } Usage example:\n1 2 3 4 5 6 7 8 .hello { font-family: frankfont Monaco Arial, Verdana, Tahoma, sans-serif; font-size: 20px; width: 300px; font-weight: bold; color: var(--color-black); background: rgba(153, 221, 153, 0.8); } Result:\nThe “hello css module” text uses our custom font. Image compression and sprite generation look like this:\nWrap-Up That covers the basics for this lesson. There is more you could do; I may write more when I have time.\n","permalink":"https://yy-tech.online/post/react-with-webpack-6/","summary":"\u003cblockquote\u003e\n\u003cp\u003eThis is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch.\nIt shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling.\nIt also covers project essentials such as \u003ccode\u003e.gitignore\u003c/code\u003e, code formatting, per-environment configuration,\nhot reload, debugging setup, and similar topics.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"webpack-4-images-and-fonts\"\u003eWebpack 4: Images and Fonts\u003c/h1\u003e\n\u003ch2 id=\"code\"\u003eCode\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/hyyfrank/webpack4\"\u003ehttps://github.com/hyyfrank/webpack4\u003c/a\u003e branch: feature/lesson7\u003c/p\u003e\n\u003ch2 id=\"preparation\"\u003ePreparation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eWhat we need to do\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSupport jpeg, jpg, gif, png, and similar formats\u003c/p\u003e","title":"React With Webpack (6)"},{"content":" This is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch. It shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling. It also covers project essentials such as .gitignore, code formatting, per-environment configuration, hot reload, debugging setup, and similar topics.\nHow Webpack 4 Handles CSS github demo branch: feature/lesson5 What We Need to Do Support CSS processing Extract CSS into separate CSS files Support CSS Modules Support modern CSS features (e.g. CSS Next) Support CSS style linting Remove unused CSS Use PostCSS for tasks such as autoprefixer and css-next Minimize CSS files Loaders and Plugins We Need Loaders transform module source code. They let you preprocess files when you import or “load” a module—similar to tasks in other build tools, and a powerful way to handle frontend build steps. Loaders can turn TypeScript into JavaScript, inline images into data URLs, or even let you import CSS directly from JavaScript modules!\nloaders: sass-loader: converts Sass to CSS postcss-loader: PostCSS is powerful; think of it roughly as css → AST → plugins → output. Almost anything has a plugin. css-loader: The css-loader interprets @import and url() like import/require() and will resolve them. We use options such as modules and localIdentName. style-loader: Adds CSS to the DOM by injecting a \u0026lt;style\u0026gt; tag plugins: mini-css-extract-plugin: extracts CSS into separate files purifycss-webpack: removes unused CSS selectors stylelint-webpack-plugin: lints CSS optimize-css-assets-webpack-plugin: optimizes and minifies CSS during the webpack build; defaults to cssnano as the processor (cssnano is also a PostCSS plugin) That’s enough theory—here is the code. To keep things clear, we pull CSS handling into its own file and merge it with webpack-merge. Below is the CSS setup:\nWe extract the config into a separate file. The older extract-text-webpack-plugin can still work; with webpack 4 you need extract-text-webpack-plugin at ^4.0.0-beta.0. The commented-out bits below are for you to try. Webpack 4 recommends mini-css-extract-plugin, so we use that. Note that mini-css-extract-plugin does not support HMR, but we only use it in production, which is fine.\nStep 1: support style-loader, css-loader, sass-loader\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 const cssDevRules=[ { loader:\u0026#39;style-loader\u0026#39; }, { loader:\u0026#39;css-loader?modules\u0026amp;localIdentName=[name]_[local]_[hash:base64:5]\u0026#39;, }, { loader:\u0026#39;sass-loader\u0026#39;, } ]; const cssProdRules=[ { loader: MiniCssExtractPlugin.loader, }, { loader:\u0026#39;css-loader?modules\u0026amp;localIdentName=[name]_[local]_[hash:base64:5]\u0026#39;, }, { loader:\u0026#39;sass-loader\u0026#39;, } ]; console.log(\u0026#34;is prod:\u0026#34;+isProd); const baseConfig = { module: { rules: [ { test: /\\.(css|sass|scss)$/, use: isProd? cssProdRules:cssDevRules, exclude: /node_modules/, }, ] }, plugins: [ ], }; CSS Support Step 2: css-next / autoprefixer support\nAdd postcss-loader for autoprefixer. To use the latest CSS features without a separate plugin, use postcss-preset-env per the official docs—it includes autoprefixer. PostCSS Preset Env turns modern CSS into something most browsers understand and adds polyfills based on browser targets.\n1 npm install postcss-preset-env Update postcss.config.js:\n1 2 3 4 5 6 7 8 9 module.exports = { plugins: { \u0026#34;postcss-import\u0026#34;: {}, \u0026#34;postcss-preset-env\u0026#34;: { browsers: \u0026#34;last 2 versions\u0026#34; }, cssnano: {} } }; 1 2 3 4 5 6 7 8 9 { loader:\u0026#39;postcss-loader\u0026#39;, options: { sourceMap: true, config: { path: __dirname + \u0026#39;/postcss.config.js\u0026#39; } }, }, Style Linting Step 3: add style-lint support\nAdd stylelint to control code quality. Here we only wire it up; you define the rules yourself, or use stylelint-config-standard with the matching plugin.\n1 2 3 4 5 6 7 8 9 const StyleCssLintPlugin = require(\u0026#34;stylelint-webpack-plugin\u0026#34;); const StyleLintPlugin = new StyleCssLintPlugin({ configFile: \u0026#34;.stylelintrc\u0026#34;, context: \u0026#34;src\u0026#34;, files: \u0026#34;**/*.scss\u0026#34;, failOnError: false, quiet: false }); baseConfig.plugins = [StyleLintPlugin, MiniCssPlugin, OptimizeCSSPlugin]; Add a .stylelintrc file; for now we use stylelint-config-standard:\n1 2 3 { \u0026#34;extends\u0026#34;: \u0026#34;stylelint-config-standard\u0026#34; } Remove Redundant CSS Step 4: remove unused CSS\nPurifyCSS removes unused CSS. Some call this “CSS tree shaking”; either way, the idea is similar.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const PurifyCSSPlugin = require(\u0026#34;purifycss-webpack\u0026#34;); const PurifyCssPlugin = new PurifyCSSPlugin({ paths: glob.sync(path.join(__dirname, \u0026#34;../src/index.js\u0026#34;)), styleExtensions: [\u0026#34;.css\u0026#34;, \u0026#34;.scss\u0026#34;], purifyOptions: { whitelist: [\u0026#34;*purify*\u0026#34;] } }); baseConfig.plugins = [ MiniCssPlugin, PurifyCssPlugin, StyleLintPlugin, OptimizeCSSPlugin // new ExtractTextPlugin(\u0026#34;styles.css\u0026#34;), ]; Minimize CSS Step 5: minimize CSS\noptimize-css-assets-webpack-plugin\ncssProcessor: preprocessor that compresses and optimizes CSS; default is cssnano. It is a function that receives CSS and options and returns a promise.\ncanPrint: {bool} whether the plugin logs to the console; default true.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const OptimizeCSSAssetsPlugin = require(\u0026#34;optimize-css-assets-webpack-plugin\u0026#34;); const OptimizeCSSPlugin = new OptimizeCSSAssetsPlugin({ cssProcessor: cssnano, cssProcessorOptions: { discardComments: { removeAll: true }, // Run cssnano in safe mode to avoid // potentially unsafe transformations. safe: true }, canPrint: true }); baseConfig.plugins = [ MiniCssPlugin, PurifyCssPlugin, StyleLintPlugin, OptimizeCSSPlugin // new ExtractTextPlugin(\u0026#34;styles.css\u0026#34;), ]; Wrap-Up That covers the main pieces. For more, explore PostCSS plugins—or write your own. This series is about webpack, not PostCSS, so the rest is up to you.\n","permalink":"https://yy-tech.online/post/react-with-webpack-5/","summary":"\u003cblockquote\u003e\n\u003cp\u003eThis is a webpack 4 frontend architecture series focused on building a frontend scaffold from scratch.\nIt shows how to combine popular modern technologies—React, Redux, webpack 4, and related tooling.\nIt also covers project essentials such as \u003ccode\u003e.gitignore\u003c/code\u003e, code formatting, per-environment configuration,\nhot reload, debugging setup, and similar topics.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"how-webpack-4-handles-css\"\u003eHow Webpack 4 Handles CSS\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/hyyfrank/webpack4\"\u003egithub demo\u003c/a\u003e branch: feature/lesson5\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"what-we-need-to-do\"\u003eWhat We Need to Do\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSupport CSS processing\u003c/li\u003e\n\u003cli\u003eExtract CSS into separate CSS files\u003c/li\u003e\n\u003cli\u003eSupport CSS Modules\u003c/li\u003e\n\u003cli\u003eSupport modern CSS features (e.g. CSS Next)\u003c/li\u003e\n\u003cli\u003eSupport CSS style linting\u003c/li\u003e\n\u003cli\u003eRemove unused CSS\u003c/li\u003e\n\u003cli\u003eUse PostCSS for tasks such as autoprefixer and css-next\u003c/li\u003e\n\u003cli\u003eMinimize CSS files\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"loaders-and-plugins-we-need\"\u003eLoaders and Plugins We Need\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eLoaders transform module source code. They let you preprocess files when you import or “load” a module—similar to tasks in other build tools, and a powerful way to handle frontend build steps. Loaders can turn TypeScript into JavaScript, inline images into data URLs, or even let you \u003ccode\u003eimport\u003c/code\u003e CSS directly from JavaScript modules!\u003c/p\u003e","title":"React With Webpack (5)"},{"content":" A webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\nwebpack4 with Babel, React, CSS Module This part covers a simple setup for Babel, React, and CSS modules. We will refine later; first ship a working version. What you need Packages to install and what they do: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \u0026#34;dependencies\u0026#34;: { \u0026#34;react\u0026#34;: \u0026#34;^16.8.1\u0026#34;, //react package \u0026#34;react-dom\u0026#34;: \u0026#34;^16.8.1\u0026#34;,//the entry point to the DOM and server renderers for React \u0026#34;webpack\u0026#34;: \u0026#34;^4.29.0\u0026#34;, // polyfill: you can use Promise, WeakMap,Array.from,Object.assign,Array.includes.. // this is a polyfill, we need it to be a dependency \u0026#34;@babel/polyfill\u0026#34;: \u0026#34;^7.2.5\u0026#34; }, \u0026#34;devDependencies\u0026#34;: { //Compile object rest and spread to ES5 \u0026#34;@babel/plugin-proposal-object-rest-spread\u0026#34;: \u0026#34;^7.3.2\u0026#34;, // re-use of Babel\u0026#39;s injected helper code to save on codesize. \u0026#34;@babel/plugin-transform-runtime\u0026#34;: \u0026#34;^7.2.0\u0026#34;, //a library that contain\u0026#39;s Babel modular runtime //helpers and a version of regenerator-runtime. \u0026#34;@babel/runtime\u0026#34;: \u0026#34;^7.0.0-beta.55\u0026#34;, //babel comman line tool. \u0026#34;@babel/cli\u0026#34;: \u0026#34;^7.2.3\u0026#34;, \u0026#34;@babel/core\u0026#34;: \u0026#34;^7.2.2\u0026#34;, //a smart preset that allows you to use the latest JavaScript without needing to //micromanage which syntax transforms \u0026#34;@babel/preset-env\u0026#34;: \u0026#34;^7.3.1\u0026#34;, //@babel/plugin-syntax-jsx //@babel/plugin-transform-react-jsx //@babel/plugin-transform-react-display-name //@babel/plugin-transform-react-jsx-self //@babel/plugin-transform-react-jsx-source \u0026#34;@babel/preset-react\u0026#34;: \u0026#34;^7.0.0\u0026#34;, \u0026#34;babel-loader\u0026#34;: \u0026#34;^8.0.5\u0026#34;, \u0026#34;babel-plugin-transform-object-rest-spread\u0026#34;: \u0026#34;^6.26.0\u0026#34;, \u0026#34;css-loader\u0026#34;: \u0026#34;^2.1.0\u0026#34;, \u0026#34;html-loader\u0026#34;: \u0026#34;^0.5.5\u0026#34;, \u0026#34;style-loader\u0026#34;: \u0026#34;^0.23.1\u0026#34;, \u0026#34;html-webpack-plugin\u0026#34;: \u0026#34;^4.0.0-beta.5\u0026#34;, \u0026#34;clean-webpack-plugin\u0026#34;: \u0026#34;^1.0.1\u0026#34;, \u0026#34;webpack-cli\u0026#34;: \u0026#34;^3.2.1\u0026#34;, \u0026#34;webpack-dev-server\u0026#34;: \u0026#34;^3.1.14\u0026#34; } Note @babel/polyfill belongs in dependencies because polyfills ship to production, not only at build time. Babel config .babelrc: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 { \u0026#34;presets\u0026#34;: [ [\u0026#34;@babel/preset-env\u0026#34;, { \u0026#34;targets\u0026#34;: { \u0026#34;node\u0026#34;: \u0026#34;current\u0026#34; } }], [\u0026#34;@babel/preset-react\u0026#34;] ], \u0026#34;plugins\u0026#34;: [ [\u0026#34;@babel/plugin-transform-runtime\u0026#34;], [\u0026#34;@babel/plugin-proposal-object-rest-spread\u0026#34;,{ \u0026#34;useBuiltIns\u0026#34;: true }] ] } Add React support webpack.config.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 const path = require(\u0026#34;path\u0026#34;); const webpack = require(\u0026#34;webpack\u0026#34;); const HtmlWebpackPlugin = require(\u0026#34;html-webpack-plugin\u0026#34;); const CleanWebpackPlugin = require(\u0026#34;clean-webpack-plugin\u0026#34;); const baseConfig = { entry: [ \u0026#34;@babel/polyfill\u0026#34;, // required here for polyfill; can also import in source \u0026#34;./src/index.js\u0026#34; ], devtool: \u0026#34;cheap-module-source-map\u0026#34;, // source map for production module: { rules: [ { test: /\\.css$/, use: [ { loader: \u0026#34;style-loader\u0026#34; }, { // use CSS modules and the modules query string format loader: \u0026#34;css-loader?modules\u0026amp;localIdentName=[name]_[hash:base64:5]\u0026#34; } ], exclude: /node_modules/ }, { test: /\\.(js|jsx)$/, exclude: /node_modules/, use: { // run js/jsx through babel-loader loader: \u0026#34;babel-loader\u0026#34; } }, { test: /\\.html$/, use: [ { loader: \u0026#34;html-loader\u0026#34; } ] } ] }, plugins: [ new CleanWebpackPlugin([\u0026#34;dist\u0026#34;]), new HtmlWebpackPlugin({ template: path.resolve(__dirname, \u0026#34;src\u0026#34;, \u0026#34;index.html\u0026#34;), // template filename: \u0026#34;index.html\u0026#34;, hash: true // cache busting }), new webpack.HotModuleReplacementPlugin() ], resolve: { extensions: [\u0026#34;*\u0026#34;, \u0026#34;.js\u0026#34;, \u0026#34;.jsx\u0026#34;] }, output: { publicPath: \u0026#34;/\u0026#34;, path: path.resolve(__dirname, \u0026#34;dist\u0026#34;), filename: \u0026#34;[name]-bundle.js\u0026#34; } }; // in development, enable HMR and inline-source-map if (process.env.NODE_ENV === \u0026#34;development\u0026#34;) { baseConfig.devtool = \u0026#34;inline-source-map\u0026#34;; baseConfig.devServer = { contentBase: \u0026#34;./dist\u0026#34;, hot: true, open: true }; } module.exports = baseConfig; First JSX A minimal JSX component: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import React from \u0026#34;react\u0026#34;; import * as style from \u0026#34;../css/main.css\u0026#34;; const HomeComponent = () =\u0026gt; { // test object rest/spread let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(x); // 1 console.log(y); // 2 console.log(z); // { a: 3, b: 4 } // test Array.from const arr = Array.from(new Set([1, 2, 3, 2, 1])); const arr2 = [1, [2, 3], [4, [5]]].flat(2); console.log(arr2); // test Promise const promise = new Promise((resolve, reject) =\u0026gt; { console.log(\u0026#34;promise\u0026#34;); resolve(1); }); // test Symbol const sym = Symbol(); console.log(\u0026#34;symbol:\u0026#34; + sym.toString()); return ( \u0026lt;div\u0026gt; \u0026lt;h2\u0026gt;Hello React16.7.0!\u0026lt;/h2\u0026gt; \u0026lt;div className={style.hello}\u0026gt;Hello CSS Module!\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; ); }; export default HomeComponent; At this point the simplest React example runs. Entry index.js:\n1 2 3 4 import React from \u0026#34;react\u0026#34;; import ReactDOM from \u0026#34;react-dom\u0026#34;; import HomeComponent from \u0026#34;./components/home\u0026#34;; ReactDOM.render(\u0026lt;HomeComponent /\u0026gt;, document.getElementById(\u0026#34;app\u0026#34;)); Scripts in package.json:\n1 2 3 4 \u0026#34;scripts\u0026#34;: { \u0026#34;prod\u0026#34;: \u0026#34;webpack --mode production\u0026#34;, \u0026#34;dev\u0026#34;: \u0026#34;NODE_ENV=development webpack-dev-server --mode development --open\u0026#34; }, Conclusion We only wired up the minimum React stack. Next we will extend this baseline step by step until the app feels more professional.\n","permalink":"https://yy-tech.online/post/react-with-webpack-4/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"webpack4-with-babel-react-css-module\"\u003ewebpack4 with Babel, React, CSS Module\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eThis part covers a simple setup for Babel, React, and CSS modules. We will refine later; first ship a working version.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"what-you-need\"\u003eWhat you need\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ePackages to install and what they do:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003e\u0026#34;dependencies\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;react\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^16.8.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//react package\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;react-dom\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^16.8.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e//the entry point to the DOM and server renderers for React\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;webpack\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^4.29.0\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// polyfill: you can use Promise, WeakMap,Array.from,Object.assign,Array.includes..\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// this is a polyfill, we need it to be a dependency\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/polyfill\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.2.5\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;devDependencies\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//Compile object rest and spread to ES5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/plugin-proposal-object-rest-spread\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.3.2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// re-use of Babel\u0026#39;s injected helper code to save on codesize.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/plugin-transform-runtime\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.2.0\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//a library that contain\u0026#39;s Babel modular runtime\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//helpers and a version of regenerator-runtime.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/runtime\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.0.0-beta.55\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//babel comman line tool.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/cli\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.2.3\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/core\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.2.2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//a smart preset that allows you to use the latest JavaScript without needing to        //micromanage which syntax transforms\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/preset-env\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.3.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//@babel/plugin-syntax-jsx\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//@babel/plugin-transform-react-jsx\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//@babel/plugin-transform-react-display-name\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//@babel/plugin-transform-react-jsx-self\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e//@babel/plugin-transform-react-jsx-source\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/preset-react\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^7.0.0\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;babel-loader\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^8.0.5\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;babel-plugin-transform-object-rest-spread\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^6.26.0\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;css-loader\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^2.1.0\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;html-loader\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^0.5.5\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;style-loader\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^0.23.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;html-webpack-plugin\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^4.0.0-beta.5\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;clean-webpack-plugin\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^1.0.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;webpack-cli\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^3.2.1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;webpack-dev-server\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;^3.1.14\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cul\u003e\n\u003cli\u003eNote \u003ccode\u003e@babel/polyfill\u003c/code\u003e belongs in \u003ccode\u003edependencies\u003c/code\u003e because polyfills ship to production, not only at build time. Babel config \u003ccode\u003e.babelrc\u003c/code\u003e:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;presets\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;@babel/preset-env\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"s2\"\u003e\u0026#34;targets\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s2\"\u003e\u0026#34;node\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;current\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;@babel/preset-react\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"s2\"\u003e\u0026#34;plugins\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;@babel/plugin-transform-runtime\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;@babel/plugin-proposal-object-rest-spread\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,{\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;useBuiltIns\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e \u003cspan class=\"p\"\u003e}]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"add-react-support\"\u003eAdd React support\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ewebpack.config.js\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e72\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003epath\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;path\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ewebpack\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;webpack\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eHtmlWebpackPlugin\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;html-webpack-plugin\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eCleanWebpackPlugin\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003erequire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;clean-webpack-plugin\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ebaseConfig\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;@babel/polyfill\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// required here for polyfill; can also import in source\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;./src/index.js\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003edevtool\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;cheap-module-source-map\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// source map for production\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003emodule\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003erules\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\.css$/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003eloader\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;style-loader\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"c1\"\u003e// use CSS modules and the modules query string format\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003eloader\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;css-loader?modules\u0026amp;localIdentName=[name]_[hash:base64:5]\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003eexclude\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/node_modules/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\.(js|jsx)$/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003eexclude\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/node_modules/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"c1\"\u003e// run js/jsx through babel-loader\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"nx\"\u003eloader\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;babel-loader\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\.html$/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003eloader\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;html-loader\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eplugins\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003eCleanWebpackPlugin\u003c/span\u003e\u003cspan class=\"p\"\u003e([\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;dist\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003eHtmlWebpackPlugin\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003etemplate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003e__dirname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;src\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;index.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"c1\"\u003e// template\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003efilename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;index.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003ehash\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e \u003cspan class=\"c1\"\u003e// cache busting\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003ewebpack\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eHotModuleReplacementPlugin\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eextensions\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;*\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;.js\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;.jsx\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003eoutput\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003epublicPath\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;/\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003e__dirname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;dist\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003efilename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;[name]-bundle.js\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// in development, enable HMR and inline-source-map\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eprocess\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eenv\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eNODE_ENV\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;development\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003ebaseConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edevtool\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;inline-source-map\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003ebaseConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edevServer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003econtentBase\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./dist\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ehot\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003emodule\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eexports\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ebaseConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"first-jsx\"\u003eFirst JSX\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eA minimal JSX component:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"nx\"\u003eReact\u003c/span\u003e \u003cspan class=\"nx\"\u003efrom\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;react\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"nx\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003estyle\u003c/span\u003e \u003cspan class=\"nx\"\u003efrom\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;../css/main.css\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eHomeComponent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c1\"\u003e// test object rest/spread\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...\u003c/span\u003e\u003cspan class=\"nx\"\u003ez\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ey\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eb\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ey\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ez\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// { a: 3, b: 4 }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c1\"\u003e// test Array.from\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003earr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eArray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nx\"\u003eSet\u003c/span\u003e\u003cspan class=\"p\"\u003e([\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003earr2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e]]].\u003c/span\u003e\u003cspan class=\"nx\"\u003eflat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003earr2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c1\"\u003e// test Promise\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003epromise\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003ePromise\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ereject\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;promise\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c1\"\u003e// test Symbol\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003esym\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eSymbol\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econsole\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;symbol:\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"nx\"\u003esym\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etoString\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003ediv\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eh2\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eHello\u003c/span\u003e \u003cspan class=\"nx\"\u003eReact16\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mf\"\u003e7.0\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/h2\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003ediv\u003c/span\u003e \u003cspan class=\"nx\"\u003eclassName\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ehello\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eHello\u003c/span\u003e \u003cspan class=\"nx\"\u003eCSS\u003c/span\u003e \u003cspan class=\"nx\"\u003eModule\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/div\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/div\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e \u003cspan class=\"nx\"\u003eHomeComponent\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eAt this point the simplest React example runs. Entry \u003ccode\u003eindex.js\u003c/code\u003e:\u003c/p\u003e","title":"React With Webpack (4)"},{"content":" A webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\nBasics entry: configure module entry points When webpack resolves files it uses context as the base directory. Default context is the directory where you run webpack—in our project that is usually the repo root. You can also set it on the CLI, e.g. webpack --context. 1 2 3 module.exports = { context: path.resolve(__dirnaame, \u0026#34;app\u0026#34;) }; Paths in entry are relative to context, which affects how later config paths are resolved. entry can be a string, array, or object. A single page might be './src/index.js'; multiple pages ['./src/firstpage.js','./src/secondpage.js']. chunk: webpack names each generated chunk. With string/array entry you get one chunk; with an object you get multiple chunks named by the object keys. Dynamic entry: For many pages and many entry points you can return an object synchronously or a Promise asynchronously: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // sync entry: () =\u0026gt; { return { first: \u0026#34;./src/firstpage\u0026#34;, second: \u0026#34;./src/sencordpage\u0026#34; }; }; // async entry: () =\u0026gt; { return new Promise(resolve =\u0026gt; { resolve({ first: \u0026#34;./src/firstpage\u0026#34;, second: \u0026#34;./src/secondpage\u0026#34; }); }); }; output: configure emitted bundles filename: a single string such as bundle.js; for multiple chunks use placeholders like [name].js, or [id]-[name]-[hash]-[chunkhash].js (internal variables for chunk id, name, hash, content hash). chunkFilename: e.g. filenames from CommonsChunkPlugin; same placeholders as above. path: output directory for bundles. publicPath: base URL when assets are on a CDN—try your own domain to see the effect. crossOriginLoading: when async-loaded assets need CORS; often used with JSONP injected into HTML. libraryTarget \u0026amp; library: how the bundle is exposed as a library and under what name. libraryExport: when exporting as commonjs/commonjs2, pick which submodule to export. module: rules for processing modules rules: how webpack reads and transforms modules—usually an array of loader configs. Each rule has three parts: Which files to match: test (arrays supported), include, exclude Which loader(s) to run: babel-loader, css-loader, etc. Multiple options can be passed as an object, often options: { ... }. Order: enforce pre or post to run a loader first or last. noParse: tell webpack not to parse certain files, e.g. jquery/chartjs: 1 2 3 4 5 noParse:|jquery/chartjs/ // or as a function noParse: (content) =\u0026gt;{ return /jquery/chartjs/.test(content) } parser: AMD, CommonJS, SystemJS, ES6, etc. Example: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 { moudle:{ rules:{ test: /\\.js$/, use:[\u0026#39;babel:loader\u0026#39;], parser:[ amd: false, commonjs: false, system:false, harmony:false, requireInclude: false,// disable require.include requireEnsure: false,// disable require.ensure requireContext: false,// disable require.context browserify: false, requireJs:false ] } } } resolve: how webpack finds module files alias: import shortcuts mapped to real paths: 1 2 3 4 5 resolve: { alias: { components: \u0026#34;./src/components\u0026#34;; } } import xxx from \u0026quot;components/xxx\u0026quot; becomes \u0026quot;./src/components/xxx\u0026quot;. mainFields: some packages ship different builds per environment—choose which field wins. extensions: when imports omit extensions, webpack tries these suffixes: 1 2 // try .ts, then .js, then .json extentsions:[\u0026#39;.ts\u0026#39;,\u0026#39;.js\u0026#39;,\u0026#39;.json\u0026#39;] modules: directories to search for dependencies; default includes node_modules. Example: 1 modules:[\u0026#39;./src/components\u0026#39;,\u0026#39;node_modules\u0026#39;] Then import xxx from ../../../components/xxx can become import xxx from xxx. enforeExtention: if true, imports must include a file extension or resolution fails. plugins: extend webpack We already use several; imports look similar—the important part is each plugin’s options. dev-server: devServer options hot: used with hot module replacement inline: when enabled, the dev-server client drives HMR and refresh; when off, changes run in an iframe at localhost:8080/webpack-dev-server Others worth reading in the docs: historyApiFallback, contentBase, headers, host, port, allowHosts, disableHostCheck, https, clientLogLevel, compress, open others: config can export more than a plain object target: web, node, async-node, webworker, electron-main, electron-renderer Devtool: how source maps are generated watch: rebuild on file changes external: libraries not bundled by webpack, e.g. jquery ResolveLoader: where webpack discovers loaders ","permalink":"https://yy-tech.online/post/react-with-webpack-3/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch1 id=\"basics\"\u003eBasics\u003c/h1\u003e\n\u003ch2 id=\"entry-configure-module-entry-points\"\u003eentry: configure module entry points\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eWhen webpack resolves files it uses \u003ccode\u003econtext\u003c/code\u003e as the base directory. Default \u003ccode\u003econtext\u003c/code\u003e is the directory where you run webpack—in our project that is usually the repo root. You can also set it on the CLI, e.g. \u003ccode\u003ewebpack --context\u003c/code\u003e.\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003emodule\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eexports\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003econtext\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003e__dirnaame\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;app\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003ePaths in \u003ccode\u003eentry\u003c/code\u003e are relative to \u003ccode\u003econtext\u003c/code\u003e, which affects how later config paths are resolved.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eentry\u003c/code\u003e can be a string, array, or object. A single page might be \u003ccode\u003e'./src/index.js'\u003c/code\u003e; multiple pages \u003ccode\u003e['./src/firstpage.js','./src/secondpage.js']\u003c/code\u003e.\n\u003cul\u003e\n\u003cli\u003echunk: webpack names each generated chunk. With string/array \u003ccode\u003eentry\u003c/code\u003e you get one chunk; with an object you get multiple chunks named by the object keys.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eDynamic entry:\nFor many pages and many entry points you can return an object synchronously or a Promise asynchronously:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// sync\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003efirst\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./src/firstpage\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003esecond\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./src/sencordpage\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// async\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eentry\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003ePromise\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003efirst\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./src/firstpage\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"nx\"\u003esecond\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./src/secondpage\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"output-configure-emitted-bundles\"\u003eoutput: configure emitted bundles\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003efilename: a single string such as \u003ccode\u003ebundle.js\u003c/code\u003e; for multiple chunks use placeholders like \u003ccode\u003e[name].js\u003c/code\u003e, or \u003ccode\u003e[id]-[name]-[hash]-[chunkhash].js\u003c/code\u003e (internal variables for chunk id, name, hash, content hash).\u003c/li\u003e\n\u003cli\u003echunkFilename: e.g. filenames from CommonsChunkPlugin; same placeholders as above.\u003c/li\u003e\n\u003cli\u003epath: output directory for bundles.\u003c/li\u003e\n\u003cli\u003epublicPath: base URL when assets are on a CDN—try your own domain to see the effect.\u003c/li\u003e\n\u003cli\u003ecrossOriginLoading: when async-loaded assets need CORS; often used with JSONP injected into HTML.\u003c/li\u003e\n\u003cli\u003elibraryTarget \u0026amp; library: how the bundle is exposed as a library and under what name.\u003c/li\u003e\n\u003cli\u003elibraryExport: when exporting as commonjs/commonjs2, pick which submodule to export.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"module-rules-for-processing-modules\"\u003emodule: rules for processing modules\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003erules: how webpack reads and transforms modules—usually an array of loader configs. Each rule has three parts:\n\u003cul\u003e\n\u003cli\u003eWhich files to match: test (arrays supported), include, exclude\u003c/li\u003e\n\u003cli\u003eWhich loader(s) to run: babel-loader, css-loader, etc. Multiple options can be passed as an object, often \u003ccode\u003eoptions: { ... }\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eOrder: enforce \u003ccode\u003epre\u003c/code\u003e or \u003ccode\u003epost\u003c/code\u003e to run a loader first or last.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003enoParse: tell webpack not to parse certain files, e.g. jquery/chartjs:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003enoParse\u003c/span\u003e\u003cspan class=\"o\"\u003e:|\u003c/span\u003e\u003cspan class=\"nx\"\u003ejquery\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"nx\"\u003echartjs\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// or as a function\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003enoParse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003econtent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e=\u0026gt;{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"err\"\u003e/jquery/chartjs/.test(content)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003eparser: AMD, CommonJS, SystemJS, ES6, etc. Example:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003emoudle\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nx\"\u003erules\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003etest\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sr\"\u003e/\\.js$/\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;babel:loader\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nx\"\u003eparser\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003eamd\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ecommonjs\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003esystem\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003eharmony\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003erequireInclude\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e// disable require.include\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003erequireEnsure\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e// disable require.ensure\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003erequireContext\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e// disable require.context\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003ebrowserify\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nx\"\u003erequireJs\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"resolve-how-webpack-finds-module-files\"\u003eresolve: how webpack finds module files\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ealias: import shortcuts mapped to real paths:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-javascript\" data-lang=\"javascript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nx\"\u003eresolve\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nx\"\u003ealias\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nx\"\u003ecomponents\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;./src/components\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ccode\u003eimport xxx from \u0026quot;components/xxx\u0026quot;\u003c/code\u003e becomes \u003ccode\u003e\u0026quot;./src/components/xxx\u0026quot;\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003emainFields: some packages ship different builds per environment—choose which field wins.\u003c/li\u003e\n\u003cli\u003eextensions: when imports omit extensions, webpack tries these suffixes:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e// try .ts, then .js, then .json\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eextentsions:[\u0026#39;.ts\u0026#39;,\u0026#39;.js\u0026#39;,\u0026#39;.json\u0026#39;]\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003emodules: directories to search for dependencies; default includes \u003ccode\u003enode_modules\u003c/code\u003e. Example:\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emodules:[\u0026#39;./src/components\u0026#39;,\u0026#39;node_modules\u0026#39;]\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003eThen \u003ccode\u003eimport xxx from ../../../components/xxx\u003c/code\u003e can become \u003ccode\u003eimport xxx from xxx\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eenforeExtention: if true, imports must include a file extension or resolution fails.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"plugins-extend-webpack\"\u003eplugins: extend webpack\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eWe already use several; imports look similar—the important part is each plugin’s options.\n\u003cul\u003e\n\u003cli\u003edev-server: devServer options\n\u003cul\u003e\n\u003cli\u003ehot: used with hot module replacement\u003c/li\u003e\n\u003cli\u003einline: when enabled, the dev-server client drives HMR and refresh; when off, changes run in an iframe at localhost:8080/webpack-dev-server\u003c/li\u003e\n\u003cli\u003eOthers worth reading in the docs: historyApiFallback, contentBase, headers, host, port, allowHosts, disableHostCheck, https, clientLogLevel, compress, open\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eothers: config can export more than a plain object\n\u003cul\u003e\n\u003cli\u003etarget: web, node, async-node, webworker, electron-main, electron-renderer\u003c/li\u003e\n\u003cli\u003eDevtool: how source maps are generated\u003c/li\u003e\n\u003cli\u003ewatch: rebuild on file changes\u003c/li\u003e\n\u003cli\u003eexternal: libraries not bundled by webpack, e.g. jquery\u003c/li\u003e\n\u003cli\u003eResolveLoader: where webpack discovers loaders\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"React With Webpack (3)"},{"content":" A webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\nversion in package.json What is the difference between ^ and ~ in package.json? They control which versions of a dependency your project may use. For example 3.4.5 follows MAJOR.MINOR.PATCH (semantic versioning). Official site: https://semver.org/. MAJOR: incompatible API changes MINOR: backward-compatible new functionality PATCH: backward-compatible bug fixes Example: you ship API version 1.0.0, fix four bugs → 1.0.4, add backward-compatible APIs → 1.1.0, fix two more bugs → 1.1.2. If a release breaks dependents, that is 2.0.0, and so on. In package.json, ~3.4.5 means \u0026gt;=3.4.5 \u0026lt;3.5.0 (patch updates within the minor line). ^3.4.5 means \u0026gt;=3.4.5 \u0026lt;4.0.0 (any compatible 3.x). See the link above for details. npm install antd --save often records ^3.13.0—you can use any 3.x below 4.0.0. There are edge cases for 0.x versions; roughly, treat ^ like ~ for those—check the official page. Before hot module replacement (HMR), a few prerequisites. We continue from the last example: html-webpack-plugin html-webpack-plugin generates HTML for you. Without it, after a build your JS lives under dist/ (the docs often use dist, so we rename build to dist). You would still hand-edit HTML to point at the new bundle paths. This plugin generates HTML and injects references to the JS in dist. Example:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 plugins: [ new HtmlWebpackPlugin({ // template; you can point at a template but need a loader—here we use html-loader template: path.resolve(__dirname, \u0026#34;src\u0026#34;, \u0026#34;index.html\u0026#34;), // output file name, default index.html, path relative to webpackConfig.output.path filename: \u0026#34;index.html\u0026#34;, // cache busting: adds a query param so the browser treats each build as a new file; similar idea to incremental deploys with new asset names hash: true, // minify options—see the plugin docs if unsure minify: { collapseWhitespace: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, removeAttributeQuotes: true }, meta: { viewport: \u0026#34;width=device-width, initial-scale=1, shrink-to-fit=no\u0026#34;, \u0026#34;theme-color\u0026#34;: \u0026#34;#4285f4\u0026#34; } }) ]; Generated HTML looks like this—the first view is minified, the second after format, because we enabled minify. Note publicPath in webpack.config.js: if set, the script src becomes something like publicpath/bundle.js?71ac66103d2a.\n1 2 3 4 5 6 7 8 9 10 11 12 13 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt;\u0026lt;/html\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=UTF-8\u0026gt; \u0026lt;meta name=viewport content=\u0026#34;width=device-width,initial-scale=1\u0026#34;\u0026gt; \u0026lt;meta http-equiv=X-UA-Compatible content=\u0026#34;ie=edge\u0026#34;\u0026gt; \u0026lt;meta name=viewport content=\u0026#34;width=device-width,initial-scale=1,shrink-to-fit=no\u0026#34;\u0026gt; \u0026lt;meta name=theme-color content=#4285f4\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt;HTML WEBPACK PLUGIN TEMPLATE. \u0026lt;script src=bundle.js?71ac66103d2a01102753\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; clean-webpack-plugin We used an npm package to delete directories before; webpack has a plugin for that too:\n1 2 3 plugins:[ new CleanWebpackPlugin([\u0026#39;dist\u0026#39;]), ] css plugin For CSS I originally wanted mini-css-extract-plugin, but it did not support HMR at the time, so the classic loaders are fine:\n1 2 3 4 5 6 7 8 9 module: { rules: [ { test: /\\.css$/, use: [\u0026#39;style-loader\u0026#39;, \u0026#39;css-loader\u0026#39;] } ] } webpack-dev-server Next configure webpack-dev-server and HotModuleReplacementPlugin:\n1 new webpack.HotModuleReplacementPlugin(); Dev server in webpack:\n1 2 3 4 devServer: { contentBase: \u0026#39;./dist\u0026#39;, hot: true }, final package.json Install every plugin with cnpm. package.json:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 { \u0026#34;name\u0026#34;: \u0026#34;webpack4\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;index.js\u0026#34;, \u0026#34;repository\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;git\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;git+https://github.com/hyyfrank/webpack4.git\u0026#34; }, \u0026#34;keywords\u0026#34;: [], \u0026#34;author\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;license\u0026#34;: \u0026#34;ISC\u0026#34;, \u0026#34;bugs\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;https://github.com/hyyfrank/webpack4/issues\u0026#34; }, \u0026#34;scripts\u0026#34;: { \u0026#34;build\u0026#34;: \u0026#34;webpack --watch\u0026#34;, \u0026#34;dev\u0026#34;: \u0026#34;webpack-dev-server\u0026#34; }, \u0026#34;homepage\u0026#34;: \u0026#34;https://github.com/hyyfrank/webpack4#readme\u0026#34;, \u0026#34;dependencies\u0026#34;: { \u0026#34;webpack\u0026#34;: \u0026#34;^4.29.0\u0026#34; }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;clean-webpack-plugin\u0026#34;: \u0026#34;^1.0.1\u0026#34;, \u0026#34;css-loader\u0026#34;: \u0026#34;^2.1.0\u0026#34;, \u0026#34;html-loader\u0026#34;: \u0026#34;^0.5.5\u0026#34;, \u0026#34;html-webpack-plugin\u0026#34;: \u0026#34;^4.0.0-beta.5\u0026#34;, \u0026#34;style-loader\u0026#34;: \u0026#34;^0.23.1\u0026#34;, \u0026#34;webpack-cli\u0026#34;: \u0026#34;^3.2.1\u0026#34;, \u0026#34;webpack-dev-server\u0026#34;: \u0026#34;^3.1.14\u0026#34; } } final webpack.config.js Final webpack.config.js:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const path = require(\u0026#34;path\u0026#34;); const webpack = require(\u0026#34;webpack\u0026#34;); const HtmlWebpackPlugin = require(\u0026#34;html-webpack-plugin\u0026#34;); const CleanWebpackPlugin = require(\u0026#34;clean-webpack-plugin\u0026#34;); module.exports = { entry: { app: \u0026#34;./src/index.js\u0026#34; }, devtool: \u0026#34;inline-source-map\u0026#34;, devServer: { contentBase: \u0026#34;./dist\u0026#34;, hot: true }, mode: \u0026#34;development\u0026#34;, module: { rules: [ { test: /\\.css$/, use: [\u0026#34;style-loader\u0026#34;, \u0026#34;css-loader\u0026#34;] } ] }, plugins: [ new CleanWebpackPlugin([\u0026#34;dist\u0026#34;]), new HtmlWebpackPlugin({ template: path.resolve(__dirname, \u0026#34;src\u0026#34;, \u0026#34;index.html\u0026#34;), // template filename: \u0026#34;index.html\u0026#34;, hash: true // cache busting }), new webpack.HotModuleReplacementPlugin() ], output: { publicPath: \u0026#34;/\u0026#34;, path: path.resolve(__dirname, \u0026#34;dist\u0026#34;), filename: \u0026#34;[name]-bundle.js\u0026#34; } }; Final result Open the browser inspector, Console panel—you should see [WDS] Hot Module Replacement enabled. HMR is working; edit JS and the page updates immediately.\n","permalink":"https://yy-tech.online/post/react-with-webpack-2/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"version-in-packagejson\"\u003eversion in package.json\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eWhat is the difference between \u003ccode\u003e^\u003c/code\u003e and \u003ccode\u003e~\u003c/code\u003e in package.json?\n\u003cul\u003e\n\u003cli\u003eThey control which versions of a dependency your project may use. For example \u003ccode\u003e3.4.5\u003c/code\u003e follows MAJOR.MINOR.PATCH (semantic versioning). Official site: \u003ca href=\"https://semver.org/\"\u003ehttps://semver.org/\u003c/a\u003e.\n\u003cul\u003e\n\u003cli\u003eMAJOR: incompatible API changes\u003c/li\u003e\n\u003cli\u003eMINOR: backward-compatible new functionality\u003c/li\u003e\n\u003cli\u003ePATCH: backward-compatible bug fixes\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eExample: you ship API version \u003ccode\u003e1.0.0\u003c/code\u003e, fix four bugs → \u003ccode\u003e1.0.4\u003c/code\u003e, add backward-compatible APIs → \u003ccode\u003e1.1.0\u003c/code\u003e, fix two more bugs → \u003ccode\u003e1.1.2\u003c/code\u003e. If a release breaks dependents, that is \u003ccode\u003e2.0.0\u003c/code\u003e, and so on.\u003c/li\u003e\n\u003cli\u003eIn package.json, \u003ccode\u003e~3.4.5\u003c/code\u003e means \u003ccode\u003e\u0026gt;=3.4.5 \u0026lt;3.5.0\u003c/code\u003e (patch updates within the minor line). \u003ccode\u003e^3.4.5\u003c/code\u003e means \u003ccode\u003e\u0026gt;=3.4.5 \u0026lt;4.0.0\u003c/code\u003e (any compatible 3.x). See the link above for details.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enpm install antd --save\u003c/code\u003e often records \u003ccode\u003e^3.13.0\u003c/code\u003e—you can use any 3.x below 4.0.0. There are edge cases for \u003ccode\u003e0.x\u003c/code\u003e versions; roughly, treat \u003ccode\u003e^\u003c/code\u003e like \u003ccode\u003e~\u003c/code\u003e for those—check the official page.\u003c/li\u003e\n\u003cli\u003eBefore hot module replacement (HMR), a few prerequisites. We continue from the last example:\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"html-webpack-plugin\"\u003ehtml-webpack-plugin\u003c/h2\u003e\n\u003cp\u003ehtml-webpack-plugin generates HTML for you. Without it, after a build your JS lives under \u003ccode\u003edist/\u003c/code\u003e (the docs often use \u003ccode\u003edist\u003c/code\u003e, so we rename \u003ccode\u003ebuild\u003c/code\u003e to \u003ccode\u003edist\u003c/code\u003e). You would still hand-edit HTML to point at the new bundle paths. This plugin generates HTML and injects references to the JS in \u003ccode\u003edist\u003c/code\u003e. Example:\u003c/p\u003e","title":"React With Webpack (2)"},{"content":" A webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\nwebpack scaffold Environment First: development environment Use VS Code and github. Concepts are covered in many places already, so I will keep this brief—see the docs. OK, let us start with how to use it. We will build the features a typical project needs one by one. First, a small example to see what the bundling flow looks like—no long talk.\nInitialize the project with npm (yarn works too). Run npm init -y to generate package.json (cnpm is a bit faster if you switch to it).\nInstall the HTML Boilerplate plugin in VS Code, then writing HTML is comfortable. Create a file and type html:5 + Enter to get a simple HTML5 file.\nAdd a simple CSS file and JS file—the classic trio—and you have the simplest possible web page.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 \u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u0026gt; \u0026lt;meta http-equiv=\u0026#34;X-UA-Compatible\u0026#34; content=\u0026#34;ie=edge\u0026#34;\u0026gt; \u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;./main.css\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Hello Webpack\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;h2\u0026gt;Say hello to webpack4!\u0026lt;/h2\u0026gt; \u0026lt;script src=\u0026#34;./bundle.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; http-server To quickly preview the HTML page, install a helper globally: cnpm install http-server -g Since we will use webpack, install it too: cnpm install webpack -g Start the page with http-server: http-server -p 3000, then visit http://127.0.0.1:3000/ to see the simple page Getting started with webpack The simple static page is done. Next we use webpack to bundle and minify JS.\nTry it once: ./node_modules/webpack/bin/webpack.js ./main.js bundle.js Then change the script src in HTML to bundle.js, open the page—it still works. Webpack packed main.js into bundle.js. Open the bundle and see what the output looks like. Of course we should not edit HTML and type commands by hand every time. Webpack gives you a config file, and with scripts in package.json you can add shortcuts so you are not typing commands all day. Formal bundling webpack.config.js looks like this: 1 2 3 4 5 6 7 8 9 10 11 const path = require(\u0026#34;path\u0026#34;); module.exports = { entry: { app: \u0026#34;./src/main.js\u0026#34; }, output: { publicPath: __dirname + \u0026#34;/build/\u0026#34;, // JS public path or CDN base path: path.resolve(__dirname, \u0026#34;build\u0026#34;), // output directory for bundles filename: \u0026#34;bundle.js\u0026#34; } }; Result Similar to the CLI run above, but shown through a config file—meaning what the comments say. Do not know entry and output? Please skim the docs (Chinese is fine) for a rough idea [see the link at the top]. After writing this, run webpack in the project root. Put the command in package.json scripts so later you run npm run build for the build. Example (webpack installed globally here for convenience): Put the command in package.json 1 2 \u0026#34;build\u0026#34;: \u0026#34;webpack\u0026#34; OK, each build creates a build directory. I do not want to delete it manually every time, so run a clean before build. Install cnpm install rmdir-cli, then the build script becomes: 1 \u0026#34;build\u0026#34;: \u0026#34;rmdir-cli build \u0026amp;\u0026amp; webpack --watch\u0026#34; Adjust the layout slightly: add a src folder for JS and only change the entry path in webpack.config.js. If HTML references the bundle, point the script src at build/. See my GitHub repo for full code. watch recompiles when files change so you see updates immediately. Bundled output for different module styles Webpack supports ES6, CommonJS, and AMD in your JS. Example with ES6:\nmain.js\n1 2 3 4 5 import addtwo from \u0026#34;./add\u0026#34;; console.log(\u0026#34;javascript say hello.\u0026#34;); addtwo(1, 2); add.js\n1 2 3 4 5 export default (a, b) =\u0026gt; { console.log(\u0026#34;a+b =\u0026#34;, a + b); return a + b; }; Rebuild, run, open Chrome DevTools on the HTML page, and check that a+b = 3 is logged. Done!\nA peek at the bundle:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 !(function(e) { var t = {}; function r(n) { if (t[n]) return t[n].exports; var o = (t[n] = { i: n, l: !1, exports: {} }); return e[n].call(o.exports, o, o.exports, r), (o.l = !0), o.exports; } (r.m = e), (r.c = t), (r.d = function(e, t, n) { r.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: n }); }), (r.r = function(e) { \u0026#34;undefined\u0026#34; != typeof Symbol \u0026amp;\u0026amp; Symbol.toStringTag \u0026amp;\u0026amp; Object.defineProperty(e, Symbol.toStringTag, { value: \u0026#34;Module\u0026#34; }), Object.defineProperty(e, \u0026#34;__esModule\u0026#34;, { value: !0 }); }), (r.t = function(e, t) { if ((1 \u0026amp; t \u0026amp;\u0026amp; (e = r(e)), 8 \u0026amp; t)) return e; if (4 \u0026amp; t \u0026amp;\u0026amp; \u0026#34;object\u0026#34; == typeof e \u0026amp;\u0026amp; e \u0026amp;\u0026amp; e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, \u0026#34;default\u0026#34;, { enumerable: !0, value: e }), 2 \u0026amp; t \u0026amp;\u0026amp; \u0026#34;string\u0026#34; != typeof e) ) for (var o in e) r.d( n, o, function(t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function(e) { var t = e \u0026amp;\u0026amp; e.__esModule ? function() { return e.default; } : function() { return e; }; return r.d(t, \u0026#34;a\u0026#34;, t), t; }), (r.o = function(e, t) { return Object.prototype.hasOwnProperty.call(e, t); }), (r.p = \u0026#34;/Users/hyy/github/webpack4/build/\u0026#34;), r((r.s = 0)); })([ function(e, t, r) { \u0026#34;use strict\u0026#34;; r.r(t); console.log(\u0026#34;javascript say hello.\u0026#34;), ((e, t) =\u0026gt; (console.log(\u0026#34;a+b =\u0026#34;, e + t), e + t))(1, 2); } ]); Getting sleepy—stopping here for today. Not sure what else to say, so I will wrap with a bit of filler!\n","permalink":"https://yy-tech.online/post/react-with-webpack-1/","summary":"\u003cblockquote\u003e\n\u003cp\u003eA webpack 4 frontend architecture series: building a scaffold from scratch, integrating React, Redux, webpack 4, gitignore, formatting, env config, HMR, debugging.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"webpack-scaffold\"\u003ewebpack scaffold\u003c/h2\u003e\n\u003ch3 id=\"environment\"\u003eEnvironment\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFirst: development environment\nUse VS Code and \u003ca href=\"https://github.com/hyyfrank/react_with_webpack\"\u003egithub\u003c/a\u003e. Concepts are covered in many places already, so I will keep this brief—see the \u003ca href=\"https://www.webpackjs.com/concepts/\"\u003edocs\u003c/a\u003e. OK, let us start with how to use it. We will build the features a typical project needs one by one. First, a small example to see what the bundling flow looks like—no long talk.\u003c/p\u003e","title":"React With Webpack (1)"},{"content":"how to track issue 1 sudo /var/log/syslog | grep cron capture the output 1 1 2 * * * /home/hyy/Start.py \u0026gt;/tmp/output.log 2\u0026gt;\u0026amp;1 check cron is running 1 ps -ef | grep cron | grep -v grep check the path is correct crontab is running in with cwd == $HOME, if you using python os.getcwd() in different folder structure, make sure you cd to the correct place or else it will affect your code by output \u0026ldquo;can not find module\u0026rdquo; stuff. in short, use absolute path in your command or add source ~/.zshrc before your crontab script, so it can find the environment variable last command in crontab should have a blank line this is tricky, if you didn\u0026rsquo;t notice it. be careful the dot thing Debian Linux and its derivative (Ubuntu, Mint, etc) have some peculiarities that may prevent your cron jobs from executing; in particular, the files in /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} must : be owned by root only be writable by root not be writable by group or other users have a name without any dots \u0026lsquo;.\u0026rsquo; or any other special character but \u0026lsquo;-\u0026rsquo; and \u0026lsquo;_\u0026rsquo; . python issue run in crontab make sure python script have #!/usr/bin/python at the beginning, not neccessary make sure log the output, so you can debug in a smooth way chmod to the script always run in normal user mode, not root user, and do not use 1 2 # don\u0026#39;t do this sudo contab -e if you try to put your log in other file, make sure the perssion of the file is good, some times, guys delete the log file via root user and create a new one with root user, this will cause the permission error.the right way is echo \u0026quot;\u0026quot; \u0026gt; logfile, then you won’t change the original file’s permission and group ","permalink":"https://yy-tech.online/post/play-with-contab/","summary":"\u003ch2 id=\"how-to-track-issue\"\u003ehow to track issue\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo /var/log/syslog \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep cron\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"capture-the-output\"\u003ecapture the output\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e * * * /home/hyy/Start.py \u0026gt;/tmp/output.log 2\u0026gt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"check-cron-is-running\"\u003echeck cron is running\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  ps -ef \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep cron \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -v grep\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"check-the-path-is-correct\"\u003echeck the path is correct\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ecrontab  is running in with cwd == $HOME, if you using python os.getcwd() in different folder structure, make sure you cd to the correct place or else it will affect your code by output \u0026ldquo;can not find module\u0026rdquo; stuff.\u003c/li\u003e\n\u003cli\u003ein short, use absolute path in your command or add \u003ccode\u003esource ~/.zshrc\u003c/code\u003e before your crontab script, so it can find the environment variable\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"last-command-in-crontab-should-have-a-blank-line\"\u003elast command in crontab should have a blank line\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ethis is tricky, if you didn\u0026rsquo;t notice it.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"be-careful-the-dot-thing\"\u003ebe careful the dot thing\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDebian Linux and its derivative (Ubuntu, Mint, etc) have some peculiarities that may prevent your cron jobs from executing; in particular, the files in /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} must :\n\u003cul\u003e\n\u003cli\u003ebe owned by root\u003c/li\u003e\n\u003cli\u003eonly be writable by root\u003c/li\u003e\n\u003cli\u003enot be writable by group or other users\u003c/li\u003e\n\u003cli\u003ehave a name without any dots \u0026lsquo;.\u0026rsquo; or any other special character but \u0026lsquo;-\u0026rsquo; and \u0026lsquo;_\u0026rsquo; .\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003epython issue run in crontab\u003c/li\u003e\n\u003cli\u003emake sure python script have #!/usr/bin/python at the beginning, not neccessary\u003c/li\u003e\n\u003cli\u003emake sure log the output, so you can debug in a smooth way\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"chmod-to-the-script\"\u003echmod to the script\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ealways run in normal user mode, not root user, and do not use\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"c1\"\u003e# don\u0026#39;t do this\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  sudo contab -e  \n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003eif you try to put your log in other file, make sure the perssion of the file is good, some times, guys delete the log file via root user and create a new one with root user, this will cause the permission error.the right way is echo \u0026quot;\u0026quot; \u0026gt; logfile, then you won’t change the original file’s permission and group\u003c/li\u003e\n\u003c/ul\u003e","title":"Crontab Issue Tracking"},{"content":"1. TODO LIST build nginx from source how to optimize the parameter how nginx process the request how to apply rolling log how to configure load balance why i have to use lua how to make force https in lua how to update the request header 2. Build from source(How To) (1).download the source file Download the nginx package from official website\nDownload pcre(version 1 and version 4.4 — 8.43), from the document of nginx, it doesn\u0026rsquo;t support pcre2. Download zlib(version 1.1.3 — 1.2.11) from official website Install openssl via sudo apt-get install openssl-dev Start to build from source 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ./configure \\ --prefix=/opt/software/nginx/ \\ --with-http_stub_status_module \\ --with-http_sub_module \\ --with-http_gzip_static_module \\ --with-pcre=../pcre-8.42 \\ --with-zlib=../zlib-1.2.11 \\ --with-openssl=../openssl-1.1.1f \\ --with-http_secure_link_module \\ --with-http_random_index_module \\ --with-http_ssl_module \\ --with-http_realip_module \\ --with-http_addition_module \\ --with-http_gzip_static_module \\ --with-cc-opt=-O3 \\ --with-http_gunzip_module \\ --with-http_random_index_module \\ --with-http_secure_link_module \\ --with-http_auth_request_module \\ --with-threads \\ --with-stream_ssl_module \\ --with-http_slice_module \\ --with-file-aio \\ --with-http_v2_module \\ --without-mail_pop3_module \\ --without-mail_imap_module \\ --without-mail_smtp_module make \u0026amp;\u0026amp; make install (2) How to optimize the parameter in the server go and edit the file /etc/sysctl.conf and activate it via /sbin/sysctl -p kernel tunning for performance, go and edit the file /etc/sysctl.conf and activate it via /sbin/sysctl -p 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # here is some configuration of tcp/ip setting in kernel net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.ip_local_port_range = 1024 65000 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_syncookies = 1 #-------------------------------- net.core.somaxconn = 262144 net.core.netdev_max_backlog = 262144 #-------------------------------- net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_reties = 1 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_keepalive_time = 30 (3) how nginx process the request nginx include two part, core and module. module include three part, core module、basic module and thirdparty module core module: http module, event module and mail module basic module: http access module, http fastcgi module, http proxy module, http rewrite module third party: http upstream request hash module, Notice module, Http access key module. how to process request http request \u0026ndash;\u0026gt; nginx core \u0026ndash;\u0026gt; handlers \u0026ndash;\u0026gt; filter1 \u0026ndash;\u0026gt; filter2 \u0026ndash;\u0026gt; \u0026hellip;more filters \u0026ndash;\u0026gt; output more detail: (4) openresty module list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 --without-http_echo_module disable ngx_http_echo_module --without-http_xss_module disable ngx_http_xss_module --without-http_coolkit_module disable ngx_http_coolkit_module --without-http_set_misc_module disable ngx_http_set_misc_module --without-http_form_input_module disable ngx_http_form_input_module --without-http_encrypted_session_module disable ngx_http_encrypted_session_module --without-http_srcache_module disable ngx_http_srcache_module --without-http_lua_module disable ngx_http_lua_module --without-http_lua_upstream_module disable ngx_http_lua_upstream_module --without-http_headers_more_module disable ngx_http_headers_more_module --without-http_array_var_module disable ngx_http_array_var_module --without-http_memc_module disable ngx_http_memc_module --without-http_redis2_module disable ngx_http_redis2_module --without-http_redis_module disable ngx_http_redis_module --without-http_rds_json_module disable ngx_http_rds_json_module --without-http_rds_csv_module disable ngx_http_rds_csv_module --without-stream_lua_module disable ngx_stream_lua_module --without-ngx_devel_kit_module disable ngx_devel_kit_module --without-stream disable TCP/UDP proxy module --without-http_ssl_module disable ngx_http_ssl_module --without-stream_ssl_module disable ngx_stream_ssl_module --with-http_iconv_module enable ngx_http_iconv_module --with-http_drizzle_module enable ngx_http_drizzle_module --with-http_postgres_module enable ngx_http_postgres_module --without-lua_cjson disable the lua-cjson library --without-lua_tablepool disable the lua-tablepool library (and by consequence, the lua-resty-shell library) --without-lua_redis_parser disable the lua-redis-parser library --without-lua_rds_parser disable the lua-rds-parser library --without-lua_resty_dns disable the lua-resty-dns library --without-lua_resty_memcached disable the lua-resty-memcached library --without-lua_resty_redis disable the lua-resty-redis library --without-lua_resty_mysql disable the lua-resty-mysql library --without-lua_resty_upload disable the lua-resty-upload library --without-lua_resty_upstream_healthcheck disable the lua-resty-upstream-healthcheck library --without-lua_resty_string disable the lua-resty-string library --without-lua_resty_websocket disable the lua-resty-websocket library --without-lua_resty_limit_traffic disable the lua-resty-limit-traffic library --without-lua_resty_lock disable the lua-resty-lock library --without-lua_resty_lrucache disable the lua-resty-lrucache library --without-lua_resty_signal disable the lua-resty-signal library (and by consequence, the lua-resty-shell library) --without-lua_resty_shell disable the lua-resty-shell library --without-lua_resty_core disable the lua-resty-core library --with-luajit=DIR use the external LuaJIT 2.1 installation specified by DIR --with-luajit-xcflags=FLAGS Specify extra C compiler flags for LuaJIT 2.1 --with-luajit-ldflags=FLAGS Specify extra C linker flags for LuaJIT 2.1 --without-luajit-lua52 Turns off the LuaJIT extensions from Lua 5.2 that may break backward compatibility --without-luajit-gc64 Turns off the LuaJIT GC64 mode (which is enabled by default on x86_64) --with-libdrizzle=DIR specify the libdrizzle 1.0 (or drizzle) installation prefix --with-libpq=DIR specify the libpq (or postgresql) installation prefix --with-pg_config=PATH specify the path of the pg_config utility ","permalink":"https://yy-tech.online/post/nginx-series-1/","summary":"\u003ch2 id=\"1-todo-list\"\u003e1. TODO LIST\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ebuild nginx from source\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow to optimize the parameter\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow nginx process the request\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow to apply rolling log\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow to configure load balance\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewhy i have to use lua\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow to make force https in lua\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehow to update the request header\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"2-build-from-sourcehow-to\"\u003e2. Build from source(How To)\u003c/h2\u003e\n\u003ch3 id=\"1download-the-source-file\"\u003e(1).download the source file\u003c/h3\u003e\n\u003cp\u003eDownload the nginx package from official website\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eDownload pcre(\u003ccode\u003eversion 1\u003c/code\u003e and \u003ccode\u003eversion 4.4 — 8.43\u003c/code\u003e), from the document of nginx, it doesn\u0026rsquo;t support pcre2.\u003c/li\u003e\n\u003cli\u003eDownload zlib(\u003ccode\u003eversion 1.1.3 — 1.2.11\u003c/code\u003e) from official website\u003c/li\u003e\n\u003cli\u003eInstall openssl via \u003ccode\u003esudo apt-get install openssl-dev\u003c/code\u003e\nStart to build from source\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./configure \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--prefix\u003cspan class=\"o\"\u003e=\u003c/span\u003e/opt/software/nginx/ \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_stub_status_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_sub_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_gzip_static_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-pcre\u003cspan class=\"o\"\u003e=\u003c/span\u003e../pcre-8.42 \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-zlib\u003cspan class=\"o\"\u003e=\u003c/span\u003e../zlib-1.2.11 \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-openssl\u003cspan class=\"o\"\u003e=\u003c/span\u003e../openssl-1.1.1f \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_secure_link_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_random_index_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_ssl_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_realip_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_addition_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_gzip_static_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-cc-opt\u003cspan class=\"o\"\u003e=\u003c/span\u003e-O3 \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_gunzip_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_random_index_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_secure_link_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_auth_request_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-threads \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-stream_ssl_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_slice_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-file-aio \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--with-http_v2_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--without-mail_pop3_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--without-mail_imap_module \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--without-mail_smtp_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e make install\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"2-how-to-optimize-the-parameter-in-the-server\"\u003e(2) How to optimize the parameter in the server\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003ego and edit the file \u003ccode\u003e/etc/sysctl.conf\u003c/code\u003e and activate it via \u003ccode\u003e/sbin/sysctl -p\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ekernel tunning for performance, go and edit the file \u003ccode\u003e/etc/sysctl.conf\u003c/code\u003e and activate it via \u003ccode\u003e/sbin/sysctl -p\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# here is some configuration of tcp/ip setting in kernel\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_max_tw_buckets \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e6000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.ip_local_port_range \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1024\u003c/span\u003e \u003cspan class=\"m\"\u003e65000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_tw_recycle \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_tw_reuse \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_syncookies \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#--------------------------------\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.core.somaxconn \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e262144\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.core.netdev_max_backlog \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e262144\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#--------------------------------\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_max_orphans \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e262144\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_max_syn_backlog \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e262144\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_synack_retries \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_syn_reties \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_fin_timeout \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enet.ipv4.tcp_keepalive_time \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e30\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"3-how-nginx-process-the-request\"\u003e(3) how nginx process the request\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003enginx include two part, core and module.\u003c/li\u003e\n\u003cli\u003emodule include three part, core module、basic module and thirdparty module\n\u003cul\u003e\n\u003cli\u003ecore module: \u003ccode\u003ehttp module\u003c/code\u003e, \u003ccode\u003eevent module\u003c/code\u003e and \u003ccode\u003email module\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ebasic module: \u003ccode\u003ehttp access module\u003c/code\u003e, \u003ccode\u003ehttp fastcgi module\u003c/code\u003e, \u003ccode\u003ehttp proxy module\u003c/code\u003e, \u003ccode\u003ehttp rewrite module\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ethird party: \u003ccode\u003ehttp upstream request hash module\u003c/code\u003e, \u003ccode\u003eNotice module\u003c/code\u003e, \u003ccode\u003eHttp access key module\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003ehow to process request\n\u003cul\u003e\n\u003cli\u003ehttp request \u0026ndash;\u0026gt; nginx core \u0026ndash;\u0026gt; handlers \u0026ndash;\u0026gt; filter1 \u0026ndash;\u0026gt; filter2 \u0026ndash;\u0026gt; \u0026hellip;more filters \u0026ndash;\u0026gt; output\u003c/li\u003e\n\u003cli\u003emore detail:\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"4-openresty-module-list\"\u003e(4) openresty module list\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_echo_module         disable ngx_http_echo_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_xss_module          disable ngx_http_xss_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_coolkit_module      disable ngx_http_coolkit_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_set_misc_module     disable ngx_http_set_misc_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_form_input_module   disable ngx_http_form_input_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_encrypted_session_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     disable ngx_http_encrypted_session_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_srcache_module      disable ngx_http_srcache_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_lua_module          disable ngx_http_lua_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_lua_upstream_module disable ngx_http_lua_upstream_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_headers_more_module disable ngx_http_headers_more_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_array_var_module    disable ngx_http_array_var_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_memc_module         disable ngx_http_memc_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_redis2_module       disable ngx_http_redis2_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_redis_module        disable ngx_http_redis_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_rds_json_module     disable ngx_http_rds_json_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_rds_csv_module      disable ngx_http_rds_csv_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-stream_lua_module        disable ngx_stream_lua_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-ngx_devel_kit_module     disable ngx_devel_kit_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-stream                   disable TCP/UDP proxy module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-http_ssl_module          disable ngx_http_ssl_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-stream_ssl_module        disable ngx_stream_ssl_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-http_iconv_module           \u003cspan class=\"nb\"\u003eenable\u003c/span\u003e ngx_http_iconv_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-http_drizzle_module         \u003cspan class=\"nb\"\u003eenable\u003c/span\u003e ngx_http_drizzle_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-http_postgres_module        \u003cspan class=\"nb\"\u003eenable\u003c/span\u003e ngx_http_postgres_module\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_cjson                disable the lua-cjson library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_tablepool            disable the lua-tablepool library \u003cspan class=\"o\"\u003e(\u003c/span\u003eand by consequence, the\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     lua-resty-shell library\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_redis_parser         disable the lua-redis-parser library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_rds_parser           disable the lua-rds-parser library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_dns            disable the lua-resty-dns library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_memcached      disable the lua-resty-memcached library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_redis          disable the lua-resty-redis library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_mysql          disable the lua-resty-mysql library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_upload         disable the lua-resty-upload library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_upstream_healthcheck\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     disable the lua-resty-upstream-healthcheck library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_string         disable the lua-resty-string library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_websocket      disable the lua-resty-websocket library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_limit_traffic  disable the lua-resty-limit-traffic library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_lock           disable the lua-resty-lock library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_lrucache       disable the lua-resty-lrucache library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_signal         disable the lua-resty-signal library \u003cspan class=\"o\"\u003e(\u003c/span\u003eand by consequence,\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     the lua-resty-shell library\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_shell          disable the lua-resty-shell library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-lua_resty_core           disable the lua-resty-core library\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-luajit\u003cspan class=\"o\"\u003e=\u003c/span\u003eDIR                  use the external LuaJIT 2.1 installation specified by DIR\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-luajit-xcflags\u003cspan class=\"o\"\u003e=\u003c/span\u003eFLAGS        Specify extra C compiler flags \u003cspan class=\"k\"\u003efor\u003c/span\u003e LuaJIT 2.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-luajit-ldflags\u003cspan class=\"o\"\u003e=\u003c/span\u003eFLAGS        Specify extra C linker flags \u003cspan class=\"k\"\u003efor\u003c/span\u003e LuaJIT 2.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-luajit-lua52             Turns off the LuaJIT extensions from Lua 5.2 that may \u003cspan class=\"nb\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     backward compatibility\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --without-luajit-gc64              Turns off the LuaJIT GC64 mode \u003cspan class=\"o\"\u003e(\u003c/span\u003ewhich is enabled by default\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                     on x86_64\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-libdrizzle\u003cspan class=\"o\"\u003e=\u003c/span\u003eDIR              specify the libdrizzle 1.0 \u003cspan class=\"o\"\u003e(\u003c/span\u003eor drizzle\u003cspan class=\"o\"\u003e)\u003c/span\u003e installation prefix\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-libpq\u003cspan class=\"o\"\u003e=\u003c/span\u003eDIR                   specify the libpq \u003cspan class=\"o\"\u003e(\u003c/span\u003eor postgresql\u003cspan class=\"o\"\u003e)\u003c/span\u003e installation prefix\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  --with-pg_config\u003cspan class=\"o\"\u003e=\u003c/span\u003ePATH              specify the path of the pg_config utility\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e","title":"Build Nginx From Source(1)"}]