美文网首页
prettier+eslint+git hooks (husky

prettier+eslint+git hooks (husky

作者: mudssky | 来源:发表于2021-04-26 17:07 被阅读0次

    prettier+eslint+git hooks (husky+lint-staged)+stylelint+typescript+vscode的配置流程

    1.先创建目录和package.json

    mkdir base
    cd base
    npm init -y
    

    2.创建git仓库

    git init
    

    把你写node用的gitignore搬过来

    # 忽略vuepress产生的缓存
    .temp/
    .cache/
    
    # Logs
    logs
    *.log
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
    lerna-debug.log*
    
    # Diagnostic reports (https://nodejs.org/api/report.html)
    report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
    
    # Runtime data
    pids
    *.pid
    *.seed
    *.pid.lock
    
    # Directory for instrumented libs generated by jscoverage/JSCover
    lib-cov
    
    # Coverage directory used by tools like istanbul
    coverage
    *.lcov
    
    # nyc test coverage
    .nyc_output
    
    # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
    .grunt
    
    # Bower dependency directory (https://bower.io/)
    bower_components
    
    # node-waf configuration
    .lock-wscript
    
    # Compiled binary addons (https://nodejs.org/api/addons.html)
    build/Release
    
    # Dependency directories
    node_modules/
    jspm_packages/
    
    # TypeScript v1 declaration files
    typings/
    
    # TypeScript cache
    *.tsbuildinfo
    
    # Optional npm cache directory
    .npm
    
    # Optional eslint cache
    .eslintcache
    
    # Microbundle cache
    .rpt2_cache/
    .rts2_cache_cjs/
    .rts2_cache_es/
    .rts2_cache_umd/
    
    # Optional REPL history
    .node_repl_history
    
    # Output of 'npm pack'
    *.tgz
    
    # Yarn Integrity file
    .yarn-integrity
    
    # dotenv environment variables file
    .env
    .env.test
    
    # parcel-bundler cache (https://parceljs.org/)
    .cache
    
    # Next.js build output
    .next
    
    # Nuxt.js build / generate output
    .nuxt
    dist
    
    # Gatsby files
    .cache/
    # Comment in the public line in if your project uses Gatsby and *not* Next.js
    # https://nextjs.org/blog/next-9-1#public-directory-support
    # public
    
    # vuepress build output
    .vuepress/dist
    
    # Serverless directories
    .serverless/
    
    # FuseBox cache
    .fusebox/
    
    # DynamoDB Local files
    .dynamodb/
    
    # TernJS port file
    .tern-port
    

    3.vscode的stylelint,eslint,prettier插件都安装上

    4.安装和配置typescript

    安装,然后创建配置文件

    npm install --save-dev typescript
    npx tsc --init
    

    需要对typescript的配置文件进行如下的修改

    lib选项比较关键,不声明使用的lib会导致es6的一些对象无法正常使用,因为typescript编译使用的类型文件不指定的话就是用你的编译目标的,默认就是es5

    指定了产物输出目录,和ts源代码所在的目录

    开启sourceMap,移除产物中的评论,开启严格模式

    "lib": ["es2015","dom"],         
     "outDir": "dist",   
      "rootDir": "src",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    
     "sourceMap": true,                           /* Generates corresponding '.map' file. */
      "removeComments": true,                      /* Do not emit comments to output. */
      "strict": true,                                 /* Enable all strict type-checking options. */
    

    5.安装prettier,eslint,stylelint

    npm install --save-dev eslint-config-prettier eslint prettier stylelint-config-prettier stylelint
    

    其中这两个npm包是用来解决prettier和lint工具的冲突的,实际作用是关闭lint工具里面和prettier会冲突的选项。所以在extends的时候放到最后面保证会覆盖前面的配置。

    stylelint-config-prettier
    eslint-config-prettier
    

    eslint内置的init选项还是挺好用的,你选几个选项就能把需要的包都安装上

    比如我如果写node的typescript程序,个人偏好无分号的standard编码风格。那么就要安装下面的插件

    npm install --save-dev @typescript-eslint/eslint-plugin@latest eslint-config-standard@latest eslint@^7.12.1 eslint-plugin-import@^2.22.1 eslint-plugin-node@^11.1.0 eslint-plugin-promise@^4.2.1 @typescript-eslint/parser@latest
    

    它会自动生成配置文件

    然后把你的prettier配置文件复制过来

    module.exports = {
      semi: false,
      singleQuote: true,
    }
    

    在eslint配置.eslintrc.js里面添加prettier兼容,prettier放在extends列表的最末端

     extends: [
        'standard',
        'prettier'
      ],
    

    stylelint配置.stylelintrc.js兼容prettier

    module.exports = {
      extends: [
        // other configs ...
        'stylelint-config-prettier',
      ],
    }
    
    

    6.安装git hooks(husky+lint-staged)

    npm install --save-dev husky lint-staged
    

    配置git hooks

    npx husky install
    npx husky add .husky/pre-commit "npx lint-staged"
    

    在package.json里添加lint-staged的配置

    "lint-staged": {
        "**/*.{js,jsx}": [
          "eslint",
          "prettier  --write"
        ],
        "**/*.{css,scss,less}": [
          "stylelint",
          "prettier  --write"
        ], 
        "**/*.{vue}": [
          "eslint",
          "stylelint",
          "prettier  --write"
        ]
      },
    

    7.powershell脚本编写脚手架实现一键搭建开发环境

    花了差不多一天时间复习了powershell,写了这个脚手架脚本

    使用方式是把这个脚本添加到环境变量或者直接放到当前目录然后执行,除了powershell运行环境,需要安装npx,npm,node才能正常运行

    base-cli.ps1 -needStyleLint -projectName testname -skipNpmInit
    

    projectname不写的话就是在当前目录安装,而不是新建一个目录cd到里面安装。

    注意eslint init的时候要选js格式的配置文件,因为目前只写了这一种配置文件的解析。

    单用powershell写脚本局限性还是挺大的,能快速出活,但是也没有nodejs里面比如说读取配置文件全部帮你搞定的包。包括代码提示之类的编码体验也差很多,而且代码可读性也差。。。

    有错误处理所以出错了会中途退出。出错了建议把出错的部分前面注销,重新执行接下来的命令。

    param(
        [string]$projectName,
        [switch]$skipNpmInit,
        [switch]$needStyleLint,
        [switch]$needGitHooks
    )
    
    # 检查上一条命令是否执行成功,如果上一条命令失败直接退出程序,退出码1
    function checkErr([string]$commandName) {
        if (-not $?) {
            # 输出执行失败信息
            write-host -ForegroundColor Red  ('checkErr: {0} exctute failed' -f $commandName)
            throw('{0} error found' -f $commandName)
            exit 1
        }
        else {
            # 上条命令执行成功后输出消息
            write-host -ForegroundColor Green  ('checkErr: {0} exctute successful' -f $commandName)
        }
    }
    function createAndInitProject([string]$projectName) {
        trap {
            write-host -ForegroundColor Red  'createAndInitProject failed' 
            break
        }
        if (-not (test-path -LiteralPath $projectName)) {
            mkdir $projectName
            Set-Location $projectName
            if ($skipNpmInit) {
                initProject -skipNpmInit
            }
            else {
                initProject
            }
        }
        else {
            write-host -ForegroundColor Red ('当前目录已经存在{0},不可重复创建,请cd到目录中执行' -f $projectName)
        }
    }
    function initNpm([switch]$skipNpmInit) {
        if ($skipNpmInit) {
            npm init -y
                
        }
        else {
            npm init
        }
        checkErr -commandName 'npm init'
    }
    function initGit {
        if (-not (Test-Path -LiteralPath '.git')) {
            git init
            checkErr -commandName 'git init'
        }  
    }
    # 使用npm初始化项目
    function initProject([switch]$skipNpmInit) {
        initNpm -skipNpmInit $skipNpmInit
             
        initGit
    }
    # 安装typescript
    function installTypeScript {
        npm install --save-dev typescript
        checkErr -commandName installTypeScript
    }
    # 创建tsconfig
    function setTsconfig {
        npx tsc  --init --lib 'es2015,dom'  --strict --sourceMap --rootDir src --outDir dist
        checkErr -commandName setTsconfig
    }
    # 如果没有eslint 配置文件,使用init进行创建,并且修改js文件使其兼容prettier
    function createEslintConfig {
        trap {
            write-host -ForegroundColor Red  'createEslintConfig failed' 
            break
        }
        
        if (-not (Test-Path -Path .eslintrc*)) {
            npx eslint --init
            checkErr -commandName 'eslint init'        
        }
        # npx eslint --init
        # checkErr -commandName 'eslint init'
        $eslintjsStr = 'module.exports = ' + (node -e "let eslintconfig = require('./.eslintrc.js');if (!eslintconfig.extends.includes('prettier')){ eslintconfig.extends.push('prettier') }; console.log(eslintconfig); ")
        $eslintjsStr | Out-File -Encoding utf8 .eslintrc.js
    }
    function createPrettierConfig {
        # 配置prettier,当前路径没有prettier配置文件才执行
        if (-not (test-path -path .prettierrc*)) {
            '{"semi":false,"singleQuote":true}' | Out-File  -Encoding utf8 .prettierrc.json
        }
    }
    function installLintAndPrettier {
        # 安装eslint-config-prettier eslint prettier
        # 选择性安装stylelint-config-prettier stylelint
        param(
            [switch]$needStyleLint
        )
        if ($needStyleLint) {
            npm install --save-dev eslint-config-prettier eslint prettier stylelint-config-prettier stylelint
            checkErr -commandName 'install eslint prettier stylelint'
            # 创建stylelint配置文件
            if (-not (Test-Path -Path .stylelintrc.* )) {
                '{"extends": ["stylelint-config-standard","stylelint-config-prettier"]}' | Out-File .stylelintrc.json
            }
        }
        else {
            npm install --save-dev eslint-config-prettier eslint prettier
            checkErr -commandName 'install eslint prettier'
        }
        createPrettierConfig
        checkErr -commandName 'create prettier config'
        createEslintConfig 
        checkErr -commandName 'create eslint config'
    }
    # 安装husky lint-staged
    function installGithooks {
        trap {
            write-host -ForegroundColor Red  'installGithooks failed' 
            break
        }
        npm install --save-dev husky lint-staged
        checkErr -commandName 'npm install --save-dev husky lint-staged'
        # 配置lint-staged
        $packageJsonHash = Get-Content package.json | ConvertFrom-Json -AsHashtable
        if ($needStyleLint) {
            $packageJsonHash["lint-staged"] = @{
                "**/*.{js,jsx}"        = "eslint", "prettier  --write";
                "**/*.{css,scss,less}" = "stylelint", "prettier  --write";
                "**/*.{vue}"           = "eslint", "stylelint", "prettier  --write";
            }
            # mv .\package.json .\package.json.back
        }
        else {
            $packageJsonHash["lint-staged"] = @{
                "**/*.{js,jsx}" = "eslint", "prettier  --write";
                "**/*.{vue}"    = "eslint", "prettier  --write";
            }
        }
        $packageJsonHash | ConvertTo-Json | Out-File -Encoding utf8 package.json
        # 添加precommithook
        npx husky install
        npx husky add .husky/pre-commit "npx lint-staged"
    }
    
    
    
    if ($projectName) {
        createAndInitProject -projectName $projectName
    }
    else {
        if (Test-Path -Path 'package.json') {
            initGit
        }
        else {
            initProject -skipNpmInit
        }
    }
    # 安装typescript本地开发依赖
    installTypeScript
    # 如果没有tsconfig,创建一个默认的
    if (-not (test-path -path tsconfig.json)) {
        setTsconfig
    }
    installLintAndPrettier -needStyleLint=$needStyleLint
    checkErr -commandName 'installLintAndPrettier'
    
    if ($needGitHooks) {
        installGithooks
        checkErr -commandName 'installGithooks'
    }
    
    # 格式化比较乱的eslint配置文件
    npx prettier -w .eslintrc.js
    
    
    

    相关文章

      网友评论

          本文标题:prettier+eslint+git hooks (husky

          本文链接:https://www.haomeiwen.com/subject/remerltx.html