{"id":13563110,"url":"https://github.com/KRISACHAN/ying-template","last_synced_at":"2025-04-03T19:32:20.770Z","repository":{"id":36232300,"uuid":"194816502","full_name":"KRISACHAN/ying-template","owner":"KRISACHAN","description":"这是一个基于 `webpack@^5.27.2` + `typescript@^4.2.3` + `esbuild-loader@^3.0.1` + `jest@^26.6.3` + `eslint@^7.22.0` 的多页面脚手架。","archived":false,"fork":false,"pushed_at":"2024-04-05T04:48:02.000Z","size":2852,"stargazers_count":127,"open_issues_count":5,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-04T15:52:18.784Z","etag":null,"topics":["docker","es6","esbuild","esbuild-loader","eslint","javascript","jest","multiple-pages","nginx","postcss","prettier","typescript","webpack","webpack5"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KRISACHAN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-02T07:57:42.000Z","updated_at":"2023-07-09T14:41:36.000Z","dependencies_parsed_at":"2024-01-19T07:10:20.781Z","dependency_job_id":"8d8d9746-9565-4608-b879-92d98ad4255a","html_url":"https://github.com/KRISACHAN/ying-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRISACHAN%2Fying-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRISACHAN%2Fying-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRISACHAN%2Fying-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KRISACHAN%2Fying-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KRISACHAN","download_url":"https://codeload.github.com/KRISACHAN/ying-template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247065406,"owners_count":20877768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","es6","esbuild","esbuild-loader","eslint","javascript","jest","multiple-pages","nginx","postcss","prettier","typescript","webpack","webpack5"],"created_at":"2024-08-01T13:01:15.264Z","updated_at":"2025-04-03T19:32:20.077Z","avatar_url":"https://github.com/KRISACHAN.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# ying-template\n\n## 项目信息\n\n这是一个基于 `webpack@^5.27.2` + `typescript@^4.2.3` + `esbuild-loader@^3.0.1,` + `jest@^26.6.3` + `eslint@^7.22.0` 的多页面脚手架。\n\n本库支持增量更新，支持 `gzip` 打包，支持第三方资源别名引入，支持静态文件引入，支持使用环境变量。\n\n## 运行环境\n\n### 安装配置\n\n1. 下载并安装 node: https://nodejs.org/zh-cn/download/\n\n### 运行命令\n\n```bash\n# 安装依赖\nyarn\n\n# 启动开发服务器\nyarn dev\n\n# 项目打包\nyarn build\n\n# 单元测试\nyarn jest\n\n# css 代码自动格式化\nyarn lint:css\n\n# js 代码自动格式化\nyarn lint:js\n\n# js \u0026 css 代码自动格式化\nyarn lint\n\n# 核心代码格式测试以及纠正\nyarn prettier\n\n# 所有代码格式测试以及纠正\nprettier:all\n\n# 一键上传以及格式化源码\nyarn cz\n\n# 安装 husky\nyarn prepare\n\n```\n\n## 项目说明\n\n### **项目结构**\n\n```txt\n├─.browserslistrc // 浏览器兼容配置\n├─.cz-config.js // commitizen 配置\n├─.editorconfig // 编辑器配置\n├─.env // 环境变量配置\n├─.eslintignore // eslint 忽略配置\n├─.eslintrc // eslint 配置\n├─.gitignore // git 忽略配置\n├─.prettierignore // prettier 忽略配置\n├─.prettierrc // prettier 配置\n├─.stylelintignore // stylelint 忽略配置\n├─.stylelintrc // stylelint 配置\n├─Dockerfile // docker 配置\n├─LICENSE // LICENSE许可\n├─README.md // 项目说明文档\n├─commitlint.config.js // commitlint 配置\n├─default.conf // 项目运行 nginx 配置\n├─docker-compose.yml\n├─fileMock.js // jest 兼容文件夹\n├─jest.config.js // Jest 配置文件\n├─nginx.conf // 项目运行 nginx 配置\n├─package.json\n├─postcss.config.js // postcss 配置文件\n├─tsconfig.json // ts 配置\n├─yarn.lock\n├─views // 页面文件夹\n├─tests // 测试文件夹\n├─static // 静态资源文件夹\n├─src // 核心代码\n├─dist // 构建产物\n├─coverage // 单元测试结果文件夹\n├─config // 核心配置夹\n|   ├─config.js // 根配置\n|   ├─dev-server.js // 开发环境服务器\n|   ├─webpack.config.base.js // 基础配置\n|   ├─webpack.config.dev.js // 开发环境配置\n|   └webpack.config.prod.js // 生产环境配置\n├─.husky\n```\n\n### 格式化方案\n\n#### prettier\n\n格式化方案为 `prettier`，主要配置如下：\n\n```javascript\n// ./.prettierrc\n{\n    \"tabWidth\": 4,\n    \"printWidth\": 80,\n    \"semi\": false,\n    \"singleQuote\": true,\n    \"trailingComma\": \"all\",\n    \"bracketSpacing\": true,\n    \"arrowParens\": \"avoid\",\n    \"requirePragma\": false,\n    \"endOfLine\": \"auto\"\n}\n```\n\n`prettier`文档链接如下：\n\n\u003chttps://prettier.io/\u003e\n\n#### eslint\n\n代码格式验证规则为`eslint`，主要配置如下：\n\n```javascript\n// ./.eslintrc\n\"rules\": {\n    \"indent\": [0, 4],\n    \"arrow-parens\": 0,\n    \"generator-star-spacing\": 0,\n    \"no-debugger\": 0,\n    \"eol-last\": 0,\n    \"eqeqeq\": 2,\n    \"camelcase\": 0,\n    \"space-before-function-paren\": 0,\n    \"quotes\": [\"error\", \"single\"],\n    \"@typescript-eslint/explicit-function-return-type\": [\n        \"off\",\n        {\n            \"allowExpressions\": true,\n            \"allowTypedFunctionExpressions\": true\n        }\n    ],\n    \"@typescript-eslint/no-explicit-any\": 2,\n    \"prettier/prettier\": \"error\",\n    \"no-var\": \"error\",\n    \"@typescript-eslint/consistent-type-definitions\": [\n        \"error\",\n        \"interface\"\n    ],\n    \"no-empty-function\": [\"error\", { \"allow\": [\"constructors\"] }],\n    \"@typescript-eslint/no-empty-function\": \"off\"\n}\n```\n\n`eslint`文档链接如下：\n\n\u003chttps://eslint.org/\u003e\n\n### 提交规范\n\n代码提交规范使用 `cz-customizable`，配置文件为`.cz-config.js`，主要配置如下：\n\n```javascript\nconst czConfig = {\n    ...,\n    types: [\n        { value: 'feat', name: '特性: 新增一个功能' },\n        { value: 'fix', name: '修复: 修复一个Bug' },\n        { value: 'docs', name: '文档: 文档变更' },\n        { value: 'style', name: '格式: 代码格式' },\n        { value: 'refactor', name: '重构: 代码重构' },\n        { value: 'perf', name: '性能: 改善性能' },\n        { value: 'test', name: '测试: 测试代码' },\n        {\n            value: 'build',\n            name:\n                '工具: 变更项目构建或外部依赖（例如scopes: webpack、gulp、npm等）',\n        },\n        {\n            value: 'ci',\n            name:\n                '集成: 更改持续集成软件的配置文件和package中的scripts命令，例如scopes: Travis, Circle等',\n        },\n        {\n            value: 'style',\n            name: '代码格式（不影响功能，例如空格、分号等格式修正）',\n        },\n        {\n            value: 'revert',\n            name: '回退: 代码回退',\n        },\n    ],\n}\n```\n\nCV 自 [Cz 工具集使用介绍 - 规范 Git 提交说明](https://juejin.im/post/6844903831893966856)\n\n使用方式，利用 `git cz` 代替 `git commit`\n\n文档链接：\n\nhttps://github.com/leoforfree/cz-customizable\n\n### commit 信息检测\n\n用 `husky` + `commitlint` 进行检测 commit 信息检测，配置代码如下：\n\n```javascript\n// ./commitlint.config.js\nmodule.exports = {\n    extends: ['@commitlint/config-conventional'],\n    // 定义规则类型\n    rules: {\n        // type 类型定义，表示 git 提交的 type 必须在以下类型范围内\n        'type-enum': [\n            2,\n            'always',\n            [\n                'feat', // 新功能\n                'fix', //  修复\n                'docs', // 文档变更\n                'style', // 代码格式（不影响代码运行的变动）\n                'refactor', // 重构（既不是增加feature）,也不是修复bug\n                'pref', // 性能优化\n                'test', // 增加测试\n                'build', // 打包\n                'ci', // 集成\n                'style', // 代码格式\n                'revert', // 回退\n            ],\n        ],\n        // subject 大小写不做校验\n        'subject-case': [0],\n    },\n}\n```\n\nCV 自 [规范化 Git 提交日志（Commitizen + husky + Git hooks ）](https://juejin.cn/post/7038550916106027044)\n\n文档链接：https://commitlint.js.org/#/\n\n### 容器化\n\n**ying-template** 添加了 **Docker** 部署 **nginx** 服务器的脚本。执行命令如下：\n\n```bash\nyarn build\ndocker-compose up\n```\n\n**Dockerfile** 内容如下\n\n```bash\nFROM nginx:1.13.12-alpine as production-stage\n\nENV SERVER_PORT=$SERVER_PORT \\\n    EXPOSE_PORT=$EXPOSE_PORT \\\n    CONTAINER_NAME=$CONTAINER_NAME \\\n    IMAGE_NAME=$IMAGE_NAME\n\nCOPY nginx.conf /etc/nginx/nginx.conf\nCOPY default.conf /etc/nginx/conf.d/default.conf\nCOPY dist /usr/share/nginx/html\n\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n\nEXPOSE ${SERVER_PORT}\n\n```\n\n**docker-compose.yml** 内容如下：\n\n```yml\nversion: '3.7'\nservices:\n    ying-front:\n        env_file:\n            - .env\n        container_name: ${CONTAINER_NAME}\n        image: ${IMAGE_NAME}\n        build:\n            context: .\n            dockerfile: Dockerfile\n        volumes:\n            - ./dist:/usr/share/nginx/html:ro\n        ports:\n            - target: ${EXPOSE_PORT}\n              published: ${SERVER_PORT}\n              protocol: tcp\n              mode: host\n```\n\n关于 **Docker** 的教程，推荐大家看这个网站：https://yeasy.gitbooks.io/docker_practice/content/ ，具体语法就不作说明了\n\n因为不想把镜像弄得太大，所以项目打包是在 `docker build` 之前完成的，有需要的可以根据各位 **DEVOPS** 的实际情况来修改\n\n### 适配方案\n\n适配方案为 `postcss-px-to-viewport` ，主要配置如下：\n\n```javascript\n// ./postcss.config.js\npxToViewport({\n    unitToConvert: 'px',\n    viewportWidth: 750,\n    viewportHeight: 1334,\n    unitPrecision: 3,\n    viewportUnit: 'vw',\n    fontViewportUnit: 'vw',\n    mediaQuery: false,\n}),\n```\n\n`postcss-px-to-viewport` 文档链接：\n\n\u003chttps://evrone.com/postcss-px-viewport\u003e\n\n### CSS 语法方案\n\nCSS 语法方案为 `precss`，主要配置如下：\n\n```javascript\n// ./postcss.config.js\nprecss({\n    stage: 3,\n    features: {\n      \t'color-mod-function': { unresolved: 'warn' }\n    }\n}),\n```\n\n`precss`文档链接：\n\n\u003chttps://github.com/jonathantneal/precss\u003e\n\n### ECMA 语法方案\n\n#### 基础方案\n\nECMA 语法的基础方案为 `esbuild-loader`，主要配置如下：\n\n```javascript\n// ./config/webpack.config.base.js\n{\n    loader: 'esbuild-loader',\n    options: {\n        loader: 'tsx',\n        target: 'esnext',\n        tsconfig: './tsconfig.json'\n    },\n},\n```\n\n已用 `esbuild-loader` 代替了 `babel-loader`，在 2023 的今年，不再考虑打包到 es5 代码\n\n### typescript\n\n支持`typescript@4.2.3`语法，`typescript`文档链接如下：\n\n\u003chttps://www.typescriptlang.org/\u003e\n\n### 环境变量\n\n使用者可在根目录下的`.env`文件添加环境变量，示例如下：\n\n```bash\nHOST=0.0.0.0 # 运行host\nPORT=8099 # 运行端口\nVERSION=2.0.0 # 当前项目版本\nPUBLIC_PATH=/ # 公共路径 https://webpack.js.org/guides/public-path/\nWATCH_ANALYZER=false # 生产环境下是否看火焰图\nIS_MOBILE=false # 判断是否是移动端，如果是，则打开postcss-px-to-viewport\n```\n\n### 单元测试\n\n### 基本说明\n\n本库使用的单元测试框架为`jest@^26.6.3`，`jest@^26.6.3`文档链接如下：\n\n\u003chttps://jestjs.io/\u003e\n\n### 注意事项\n\n**jest** 测试 **dom** 时，相关代码需要包裹在 **window.onload** 里，否则会报错。例如\n\n```javascript\n'use strict'\nimport '@/style/index.css'\nimport qrcodeImg from 'static/img/qrcode-all1.png'\n\nwindow.onload = () =\u003e {\n    const radio = 0.25\n    const width = 914\n    const height = 439\n\n    const qrcode: Element = document.querySelector('.qrcode')\n    qrcode.setAttribute('src', qrcodeImg)\n\n    console.group('%c快来撩我啊', 'color: #894e54; font-size: 60px;')\n    console.log(\n        '%c+',\n        `\n            font-size: 1px;\n            padding: ${height * radio}px ${width * radio}px;\n            background-image: url(https://fish-pond-1253945200.cos.ap-guangzhou.myqcloud.com/img/base/qrcode-all1.png);\n            background-size: contain;\n            background-repeat: no-repeat;\n            color: transparent;\n        `,\n    )\n    console.groupEnd()\n}\n\nexport const add = (a: number, b: number): number =\u003e a + b\n```\n\n### 其他配置\n\n#### 第三方插件 URL 引入\n\n当用户使用 url 的形式（例如 CDN）引入第三方 JS 文件时，可通过 `./config/webpack.config.base.js` 的 `externals` 进行配置，例子如下：\n\n```javascript\nconst baseConfig = {\n    //...\n    externals: {\n        // ...\n        jquery: 'jQuery',\n    },\n}\n```\n\n#### 请求转发\n\n用户可以在 `./config/webpack.config.dev.js` 里的 `devServer.proxy` 进行转发请求配置，例子如下：\n\n```javascript\nconst webpackDev = {\n    //...\n    devServer: {\n        // ...\n        proxy: {\n            '/api': 'http://localhost:3000',\n        },\n    },\n}\n```\n\n文档链接：\n\n\u003chttps://webpack.js.org/configuration/dev-server/#devserverproxy\u003e\n\n### 路径重定向\n\n用户可以在 `./config/config.js` 里的 `dev.alias` 配置路径重定向，例子如下：\n\n```javascript\nconst config = {\n    // ...\n    dev: {\n        alias: {\n            static: resolve('static'),\n        },\n    },\n}\n\n// .js/ts里\nimport '@/style/index.css'\n\n// .css里\n// background: url('~static/img/qrcode-all1.png') 50% 50% / cover no-repeat;\n```\n\n文档链接：\n\nhttps://webpack.js.org/configuration/resolve/#resolvealias\n\n## 后记\n\n如果你喜欢探讨技术，或者对本仓库有任何的意见或建议，非常欢迎加鱼头微信好友一起探讨，当然，鱼头也非常希望能跟你一起聊生活，聊爱好，谈天说地。\n鱼头的微信号是：krisChans95\n也可以扫码关注公众号，订阅更多精彩内容。\n\n![./static/img/qrcode-all1.png](./static/img/qrcode-all1.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKRISACHAN%2Fying-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKRISACHAN%2Fying-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKRISACHAN%2Fying-template/lists"}