-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from JackXuyi/feature/plugin
Feature/plugin
- Loading branch information
Showing
9 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,3 +102,6 @@ dist | |
|
||
# TernJS port file | ||
.tern-port | ||
|
||
yarn.lock | ||
lib/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"editor.formatOnSave": true, | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,62 @@ | ||
# develop-plugin | ||
|
||
开发过程中项目优化 | ||
|
||
## 安装 | ||
|
||
```bash | ||
npm install --save-dev @zhijianren/develop-plugin | ||
|
||
或 | ||
|
||
yarn add @zhijianren/develop-plugin --dev | ||
``` | ||
|
||
## 使用 | ||
|
||
- 加入 `loader` 收集需要检测的资源 | ||
|
||
```js | ||
module.exports = { | ||
module: { | ||
rules: [ | ||
{ | ||
test: /.(png|jpg|svg|jpeg)$/, | ||
use: ['other-loader', '@zhijianren/develop-plugin'], | ||
}, | ||
], | ||
}, | ||
} | ||
``` | ||
|
||
- 引入插件在编译文件完成之后检测对应资源目录下的文件是否使用 | ||
|
||
```js | ||
const developLoader = require('@zhijianren/develop-plugin') | ||
|
||
module.exports = { | ||
plugins: [ | ||
new developLoader.Plugin({ | ||
rootPath: [path.resolve(__dirname, '../client/static')], | ||
output: true, | ||
test: /.(png|jpg|svg|jpeg)$/, | ||
isDel: true, | ||
outputAssets: false, | ||
}), | ||
], | ||
} | ||
``` | ||
|
||
### 插件可选参数 | ||
|
||
| 参数名称 | 参数值 | 默认值 | 说明 | | ||
| :----------- | :------------------------------------ | :----- | ----------------------------------------------------------------------------------------- | | ||
| rootPath | string[] | 无 | 需要检测的资源的绝对路径 | | ||
| output | boolean \| (assets: string[]) => void | true | 输出删除的资源信息,true 通过控制台输出,false 不输出,若为函数则参数为需要删除的资源路径 | | ||
| test | RegExp | 无 | 需要检测的资源正则表达式 | | ||
| isDel | boolean | false | 是否自动删除未使用的资源 | | ||
| outputAssets | boolean | false | 是否生成对应的资源文件 | | ||
|
||
## 说明 | ||
|
||
此方案的原理是通过 loader 收集项目中使用的资源信息,然后再通过文件递归的方式检测是否使用,所以整个项目需要编译一遍,耗时可能较长 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "@zhijianren/develop-plugin", | ||
"version": "0.0.2-beta.5", | ||
"description": "开发过程中项目优化", | ||
"main": "./lib/index.js", | ||
"scripts": { | ||
"dev": "tsc --build ./tsconfig.dev.json --watch", | ||
"build": "tsc --build ./tsconfig.json", | ||
"deploy": "npm run build && npm version patch && npm publish --access=public", | ||
"deploy:beta": "npm run build && npm version prerelease --preid=beta && npm publish --access=public", | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/JackXuyi/develop-plugin.git" | ||
}, | ||
"author": "xuyi", | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/JackXuyi/develop-plugin/issues" | ||
}, | ||
"files": [ | ||
"package.json", | ||
"README.md", | ||
"LICENSE", | ||
".gitignore", | ||
"tsconfig.json", | ||
"src", | ||
"lib" | ||
], | ||
"homepage": "https://github.com/JackXuyi/develop-plugin#readme", | ||
"devDependencies": { | ||
"@types/node": "^14.14.7", | ||
"chalk": "^4.1.0", | ||
"typescript": "^4.0.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import createPluginClass from './plugin' | ||
|
||
const assets: Set<string> = new Set() | ||
|
||
function Loader(content: any) { | ||
// @ts-ignore | ||
assets.add(this.resourcePath) | ||
return content | ||
} | ||
|
||
Loader.Plugin = createPluginClass(assets) | ||
|
||
export default Loader | ||
|
||
module.exports = Loader |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import * as chalk from 'chalk' | ||
import * as path from 'path' | ||
import { getFileList, delFile } from './utils' | ||
|
||
export interface IOptions { | ||
rootPath: string[] | ||
test: RegExp | ||
isDel?: boolean | ||
output?: true | ((assets: string[]) => void) | ||
outputAssets?: boolean | ||
} | ||
|
||
const createPluginClass = (useAssets: Set<string>) => { | ||
return class { | ||
public options: IOptions | ||
|
||
constructor(options: IOptions) { | ||
this.options = options | ||
} | ||
|
||
public apply(compiler: any) { | ||
compiler.plugin('shouldEmit', () => { | ||
this.outputAssets() | ||
const { outputAssets = false } = this.options | ||
return outputAssets | ||
}) | ||
} | ||
|
||
public getAssets() { | ||
const { rootPath = [], test } = this.options | ||
const files: string[] = [] | ||
rootPath.forEach((pathname) => { | ||
const list = getFileList(path.resolve(pathname)) | ||
files.push(...list) | ||
}) | ||
return files.filter((file) => test.test(file)) | ||
} | ||
|
||
public outputAssets() { | ||
const { output, isDel } = this.options | ||
if (output) { | ||
const projectAssets = this.getAssets() | ||
const useAssetsMap: { [key: string]: true } = {} | ||
useAssets.forEach((key) => (useAssetsMap[key] = true), {}) | ||
const projectNoUseAssets = projectAssets.filter( | ||
(file) => !useAssetsMap[file], | ||
) | ||
if (isDel) { | ||
projectNoUseAssets.forEach((filename) => { | ||
if (delFile(filename)) { | ||
console.log(chalk.gray(`del file ${filename} success`)) | ||
} | ||
}) | ||
} | ||
if (typeof output === 'boolean') { | ||
console.log( | ||
chalk.red('Project do not use images list'), | ||
projectNoUseAssets, | ||
) | ||
} else if (typeof output === 'function') { | ||
output(projectNoUseAssets) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default createPluginClass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import * as fs from 'fs' | ||
import * as path from 'path' | ||
|
||
/** | ||
* 是否是文件夹 | ||
* @param pathname 文件或文件夹路径 | ||
*/ | ||
function isDir(pathname: string) { | ||
try { | ||
const state = fs.statSync(pathname) | ||
if (state.isFile()) { | ||
// 是文件 | ||
return false | ||
} else if (state.isDirectory()) { | ||
return true | ||
} | ||
} catch (e) { | ||
return false | ||
} | ||
return false | ||
} | ||
|
||
/** | ||
* 删除文件 | ||
* @param pathname 文件路径 | ||
*/ | ||
export function delFile(pathname: string) { | ||
try { | ||
fs.unlinkSync(pathname) | ||
return true | ||
} catch (e) { | ||
console.error(`del file ${pathname} error: `, e) | ||
return false | ||
} | ||
} | ||
|
||
/** | ||
* 获取当前路径下的所有文件 | ||
* @param filePath 文件或文件夹路径 | ||
*/ | ||
export function getFileList(filePath: string) { | ||
if (!isDir(filePath)) { | ||
return [filePath] | ||
} | ||
|
||
const result: string[] = [] | ||
// 根据文件路径读取文件,返回文件列表 | ||
try { | ||
const files = fs.readdirSync(filePath) | ||
files.forEach((filename) => { | ||
//获取当前文件的绝对路径 | ||
const dir = path.join(filePath, filename) | ||
if (isDir(dir)) { | ||
const temp = getFileList(dir) | ||
result.push(...temp) | ||
} else { | ||
result.push(dir) | ||
} | ||
}) | ||
} catch (e) { | ||
console.error('fileDisplay error', e) | ||
} | ||
return result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compileOnSave": true, | ||
"compilerOptions": { | ||
"preserveWatchOutput": true | ||
}, | ||
"watchOptions": { | ||
// Use native file system events for files and directories | ||
"watchFile": "useFsEvents", | ||
"watchDirectory": "useFsEvents", | ||
|
||
// Poll files for updates more frequently | ||
// when they're updated a lot. | ||
"fallbackPolling": "dynamicPriority" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"module": "CommonJS", | ||
"lib": ["es2015", "es2016", "es2017", "es6", "scriptHost"], | ||
"declaration": true, | ||
"outDir": "./lib", | ||
"declarationDir": "./lib", | ||
"strict": true, | ||
"moduleResolution": "node", | ||
"rootDir": "./src", | ||
"sourceMap": true, | ||
"allowSyntheticDefaultImports": true | ||
}, | ||
"exclude": ["./node_modules/*", "lib", "es", "dist"], | ||
"include": ["src"], | ||
"skipLibCheck": true, | ||
"skipDefaultLibCheck": true | ||
} |