Khởi tạo thư mục, file
Ở bài viết này, mình sẽ create-react-app
một project để có một vài file để test. Các bạn cũng có thể npm init
rồi tạo một vài file bất kỳ gì cũng được.
1 2 | $ npx create-react-app gencomment |
Tiếp theo chúng ta sẽ tạo 1 file gencomment.js và thêm script vào file package.json để test 1 xíu trước khi vào code nhé. Thành quả ban đầu:
1 2 3 4 5 | ├── public/ ├── src/ ├── gencomment.js ├── package.json |
1 2 3 | <span class="token comment">//gencomment.js</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'BEGIN'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
1 2 3 4 5 6 7 | <span class="token comment">//package.json</span> <span class="token punctuation">{</span> <span class="token string">"script"</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">"gencomment"</span><span class="token punctuation">:</span> <span class="token string">"node gencomment.js"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Chúng ta hãy run npm run gencomment
để đảm bảo code chạy được trước khi qua phần tiếp theo nhé. Kết quả mong muốn là sẽ log ra được message ‘BEGIN’ mọi người nhé :v
Code
OK, vào phần chính thôi nào.
Thuật toán mình nghĩ cũng đơn giản thôi:
- Đầu tiên chúng ta sẽ đọc folder để lặp qua các file và folder con (sử dụng thư viện
fs
vàpath
có sẵn) - Tiếp đến là check xem đó là một file hay là folder, nếu folder thì lặp lại Bước 1
- Nếu là file thì đọc dòng đầu tiên của file xem có comment chưa .Nếu chưa thì insert comment vào. Ở bước này, để chỉ đọc dòng đầu tiên của file mà không cần phải đọc toàn bộ file mình sẽ sử dụng package
firstline
. Package này dùng read stream khá là nhanh, và chỉ có 30 dòng code thôi, mọi người có thể xem qua nhé.
Sau một hồi search google, xem document các thứ thì đây là phần code của mình:
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 | <span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"fs"</span><span class="token punctuation">)</span> <span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"path"</span><span class="token punctuation">)</span> <span class="token keyword">const</span> firstline <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"firstline"</span><span class="token punctuation">)</span> <span class="token comment">// just allow js and jsx file for this demo</span> <span class="token keyword">const</span> config <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token constant">COMMENT</span><span class="token punctuation">:</span> <span class="token string">"// Day_la_du_an_cua_sep_***_dep_zai_ahihi"</span><span class="token punctuation">,</span> <span class="token constant">ALLOW_FILE_EXT</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"js"</span><span class="token punctuation">,</span> <span class="token string">"jsx"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token comment">/** * This function will insert comment in every file with ALLOW_FILE_EXT. * @param {String} dir A path to directory */</span> <span class="token keyword">const</span> <span class="token function-variable function">genComment</span> <span class="token operator">=</span> dir <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// loop through folder</span> fs<span class="token punctuation">.</span><span class="token function">readdirSync</span><span class="token punctuation">(</span>dir<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>view <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// if is folder: genComment folder</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>view<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> undefined<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">genComment</span><span class="token punctuation">(</span>path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>dir<span class="token punctuation">,</span> view<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// else check if is allowed file</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span><span class="token constant">ALLOW_FILE_EXT</span><span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>view<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> filePath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>dir<span class="token punctuation">,</span> view<span class="token punctuation">)</span> <span class="token comment">// check if file already has comment </span> <span class="token function">firstline</span><span class="token punctuation">(</span>filePath<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>firstLineContent <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>firstLineContent<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>config<span class="token punctuation">.</span><span class="token constant">COMMENT</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// store current content</span> <span class="token keyword">const</span> fileCurrentContent <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span>filePath<span class="token punctuation">)</span> <span class="token comment">// write comment</span> fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> <span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>config<span class="token punctuation">.</span><span class="token constant">COMMENT</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">n`</span></span><span class="token punctuation">)</span> <span class="token comment">// append current content</span> fs<span class="token punctuation">.</span><span class="token function">appendFile</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> fileCurrentContent<span class="token punctuation">,</span> err <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">throw</span> err <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">genComment</span><span class="token punctuation">(</span>path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">"src"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Vậy trường hợp chúng ta muốn xóa tất cả comment vừa insert vào thì sao 😕
Đối với trường hợp này chúng ta sẽ có 2 cách, một là tạo thêm một file removecomment.js xong rồi add thêm 1 script npm removecomment
nữa hoặc là mở rộng script hiện tại sao cho nó có thể nhận tham số add hoặc remove kiểu như sau:
1 2 3 | $ npm run gencomment add "some comment" $ npm run gencomment remove "some comment" |
Cách thứ 2 có vẻ OK hơn nhỉ, vậy chúng ta sẽ làm theo cách này xem nhé.
Đối với trường hợp này, mình sẽ sử dụng process.argv
để parse command line argument.
Kết quả
Toàn bộ code của chúng ta sẽ như sau, mình có update lại 1 xíu nhé :v
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 73 74 75 76 | <span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"fs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"path"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> firstline <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"firstline"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> config <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token constant">COMMENT_PREFIX</span><span class="token punctuation">:</span> <span class="token string">"//"</span><span class="token punctuation">,</span> <span class="token constant">ALLOW_FILE_EXT</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"js"</span><span class="token punctuation">,</span> <span class="token string">"jsx"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token constant">MODE</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token constant">ADD</span><span class="token punctuation">:</span> <span class="token string">"add"</span><span class="token punctuation">,</span> <span class="token constant">REMOVE</span><span class="token punctuation">:</span> <span class="token string">"remove"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">/** * This function will insert comment in every file with ALLOW_FILE_EXT. * @param {String} dir A path to directory */</span> <span class="token keyword">const</span> <span class="token function-variable function">genComment</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> dir<span class="token punctuation">,</span> mode<span class="token punctuation">,</span> comment <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> _comment <span class="token operator">=</span> <span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>config<span class="token punctuation">.</span><span class="token constant">COMMENT_PREFIX</span><span class="token interpolation-punctuation punctuation">}</span></span> <span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>comment<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">;</span> fs<span class="token punctuation">.</span><span class="token function">readdirSync</span><span class="token punctuation">(</span>dir<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>view <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// if is folder: genComment folder</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>view<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">===</span> undefined<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">genComment</span><span class="token punctuation">(</span><span class="token punctuation">{</span> dir<span class="token punctuation">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>dir<span class="token punctuation">,</span> view<span class="token punctuation">)</span><span class="token punctuation">,</span> mode<span class="token punctuation">,</span> comment <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// else check if is allowed file</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span><span class="token constant">ALLOW_FILE_EXT</span><span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>view<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> filePath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>dir<span class="token punctuation">,</span> view<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// check if file already has comment</span> <span class="token function">firstline</span><span class="token punctuation">(</span>filePath<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>firstLineContent <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mode <span class="token operator">===</span> <span class="token constant">MODE</span><span class="token punctuation">.</span><span class="token constant">ADD</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>firstLineContent<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>_comment<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// store current content</span> <span class="token keyword">const</span> fileCurrentContent <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span>filePath<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// write comment</span> fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> <span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>_comment<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">n`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// append current content</span> fs<span class="token punctuation">.</span><span class="token function">appendFile</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> fileCurrentContent<span class="token punctuation">,</span> err <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>firstLineContent<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>_comment<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// read file</span> fs<span class="token punctuation">.</span><span class="token function">readFile</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> <span class="token string">"utf8"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">,</span> data<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">throw</span> err<span class="token punctuation">;</span> <span class="token comment">// write all content except first line</span> fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span> filePath<span class="token punctuation">,</span> data <span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">"n"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">"n"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> mode <span class="token operator">=</span> process<span class="token punctuation">.</span>argv<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">const</span> comment <span class="token operator">=</span> process<span class="token punctuation">.</span>argv<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// Check if command line argument is valid</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token constant">MODE</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>mode<span class="token punctuation">)</span> <span class="token operator">&&</span> comment<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">genComment</span><span class="token punctuation">(</span><span class="token punctuation">{</span> dir<span class="token punctuation">:</span> path<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>__dirname<span class="token punctuation">,</span> <span class="token string">"src"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> mode<span class="token punctuation">,</span> comment<span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Chúc mọi người thành công !!