全网最详细的从0到1的turbo pnpm monorepo的前端工程化项目[搭建篇]

全网最详细的从0到1的turbo pnpm monorepo的前端工程化项目[搭建篇]

    • 引言
    • 相关环境
    • 技术栈
    • 初始化工程
    • 安装turbo
    • 配置pnpm-workspace
    • 安装husky
    • 安装lint-staged
    • 安装eslint
    • 安装prettier
    • 配置 .editorconfig
    • 配置 .gitignore
    • 初步项目结构
    • 结语

引言

最近各种原因,生活上的,工作的上的都有,特意在业余时间做一点事情!
这是一个使用 pnpm monorepo 来搭建的demo级别的组件库

相关环境

  • nodejs: node V20.11.0
  • pnpm: pnpm V8.15.0
  • win10: win10 WSL Ubuntu22
  • vscode: V1.85.0
  • git: V2.39.1

在这里插入图片描述

技术栈

  • pnpm monorepo 来进行项目管理

选择 pnpm, 正如官网所描述的 “快、省” 优秀的包管理机制,和 workspace 功能,对 monorepo 有良好的支持。monorepo 是一种项目架构,简单的来说:一个仓库内包含多个开发项目(模块,包)。为了以后更好拆分内容,又能使用公共代码,,公共的工具方法也可以在组件之间共用,其实核心就是简化代码、更有效的管理代码,而且还可以进行单独发布,monorepo 就可以很好地来实现。市面上大量开源框架都在使用 pnpm monorepo,也说明的他的优秀。

  • turbo 任务编排

选择turbo 主要是解决项目之间的依赖关系,编排构建顺序。比如我们有一个 app 依赖了我们的ui库,那么在都有更改的情况下,build 顺序就有了要求,通过 turbo 的话,一行命令就可以解决,并且可以提高构建效率。

不熟悉的turbo的,也可以看看Turborepo 其中提供了一个创建组件库的模板工程 。各种各样的模板工程
!在这里插入图片描述

初始化工程

我这次并没有使用Turborepo模板来处理,因为模板下载来依赖弄完之后还要删除,不太适合我!

  • 新建文件夹robin-design
 $ mkdir robin-design
  • 初始化 package
 $ cd robin-design$ pnpm init
  • 完善 package.json

根据自己的情况补全相应的信息,我这里是首次,只是补充一点信息,删减比较厉害,可以大概写下,后面慢慢补全!
在这里插入图片描述

  • 新建文件夹appspackages
 $ mkdir apps$ mkdir apps/admin$ mkdir apps/docs$ mkdir packages$ mkdir packages/components$ mkdir packages/tsconfig$ mkdir packages/eslint-config-common$ mkdir packages/eslint-config-vue

packages放一些ui库、工具库等相关库;apps 放一些文档库以及一些应用,比如组件开发完成之后基于UI的一套的UI admin系统,包括我后期想做一体化的管理系统,类似于jekins,不知道有没有时间去做啦!也有可能是一个空话,说这些的原因,就是你的工程你做主,只要规范、规整、简洁一目了然就行!以上就是我初步的一些东西。其他的一些文件不在写啦,后面慢慢补充吧!

安装turbo

我这边没有想官网上,进行全局安装,而是直接安装到依赖上!这个是官网的列子

  • turbo依赖
  $pnpm install turbo -Dw

在这里插入图片描述

  • 创建turbo.json
  $echo '{ "$schema": "https://turbo.build/schema.json"}' > turbo.json

在这里插入图片描述

  • 编写turbo.json

下面是官网的turbo.json说明,详细官网更直接pipeline

{"$schema": "https://turbo.build/schema.json","pipeline": {"build": {// A package's `build` script depends on that package's// dependencies and devDependencies// `build` tasks  being completed first// (the `^` symbol signifies `upstream`)."dependsOn": ["^build"],// note: output globs are relative to each package's `package.json`// (and not the monorepo root)"outputs": [".next/**", "!.next/cache/**"]},"deploy": {// A package's `deploy` script depends on the `build`,// `test`, and `lint` scripts of the same package// being completed. It also has no filesystem outputs."dependsOn": ["build", "test", "lint"]},"test": {// A package's `test` script depends on that package's// own `build` script being completed first."dependsOn": ["build"],// A package's `test` script should only be rerun when// either a `.tsx` or `.ts` file has changed in `src` or `test` folders."inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]},// A package's `lint` script has no dependencies and// can be run whenever. It also has no filesystem outputs."lint": {},"dev": {"cache": false,"persistent": true}}
}

下面是我项目里,后面继续完善

{"$schema": "https://turbo.build/schema.json","pipeline": {"build": {"dependsOn": ["^build"],"outputs": ["dist/**"]},"lint": {},"dev": {"cache": false,"persistent": true},"test": {},"test:watch": {"cache": false}}
}

tips:

  1. $schema:定义了 json 的类型,类似于 ts 对于 js 的约束
  2. dependsOn:表示当前命令所依赖的相关流程
  3. pipeline.build:表示当执行 turbo build 时会预先执行 ^build, ^build 就是所有项目的 package.json 里的那个 build 脚本,^ 是一个标记。如果像 lint 中的 build,他就指的是 pipeline 中的第一个 build 命令。
  4. outputs:指定缓存输出目录
  5. inputs: 配置的目录下文件有变化,才会重新执行此命令

配置pnpm-workspace

没啥可说的,看官网配置,在根目录下新建一个 pnpm-workspace.yaml,配置如下

  packages:- "apps/*"- "packages/*"

安装husky

husky做的事情就是在git工作流的某个时机触发脚本,也就是git hook,比如我们在git commit之前进行eslint语法检查,eslint检查过程中报错或者警告太多是会中断指令(git commit)执行,所以这样就保证了提交到远程的代码是通过eslint检查的。

  $pnpm install husky -Dw$git init$pnpm exec husky init$cd .husky$echo '' > commit-msg

在这里插入图片描述

编写 commit-msg脚本,你也可以不用编写,安装 @commitlint/config-conventional @commitlint/cli插件,在commit-msg里写上npx --no – commitlint --edit ${1}也行,具体用法,自行摸索,我这里是自定义实现,符合基本格式验证就ok啦!脚本如下

#!/usr/bin/env shecho -e "\033[33m ------------------- 正在校验提交信息格式 -------------------- \033[0m"
# 获取当前提交的 commit msg
commit_msg=$(cat "$1")# 获取用户 email
email=$(git config user.email)msg_re="^(feat|fix|perf|refactor|merge|docs|style|test|build|revert|ci|chore|release|workflow)(\(.+\))?: .{1,100}"if [[ ! $commit_msg =~ $msg_re ]]
thenecho -e "\033[35m不合法的 commit 消息提交格式,请使用正确的格式,请使用 feat|fix|perf|refactor|merge|docs|style 加冒号等开头格式\033[0m"# 异常退出exit 1
fi

husky 触发的相关命令后面在继续完善

tips: 注意husky8husky9生成还是有区别的, 请看这里

安装lint-staged

我们在实际使用中并不是针对全部的文件进行校验,因为也有可能是当前为完成不做检查和体检,所以我们只想对git add到暂存区(staged area)的文件进行lint检查,所以借助lint-staged来实现。

  $pnpm add  lint-staged -Dw

编写 lint-staged 指令, 在package.json中新增配置项

{..."lint-staged": {"<glob-pattern>": "<command>"}
}

其中 可以是原生的工具库命令,也可以是 Scripts 里的自定义命令。原生命令可以省略 pnpm run 前缀,但自定义命令必须是完整的,比如 eslint --fix 和 pnpm run lint:eslint。命令的类型可以是单个命令的字符串,也可以多个命令组成的数组。比如如下

{..."lint-staged": {"packages/**/__tests__/*.ts": "npm run test","packages/**/*.ts": ["pnpm run lint:eslint", // scripts 自定义的命令"prettier --write" // prettier 原生的命令]}
}

安装eslint

eslint本质就是一个内置有解析器的工具,它可以将项目代码解析成AST,然后根据AST抽象语法树分析出代码里存在的问题然后给出警告或者报错。eslint的初衷就是在代码编写阶段尽早得发现存在的错误;除了语法检查外,eslint也具有一定的代码格式化能力,但是不是其能力的重心(prettier在代码格式方面更加专业)。eslint官网

这个eslint 用的相对多些,配置相对复杂一点,环境也相对复杂,针对这个配置,以及适应后面的变化,在packages文件下拆成多个项目进行处理。有eslint-config-commoneslint-config-customeslint-config-vue

  • eslint-config-common 公共 eslint rules 配置, 、安装 @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-import eslint-plugin-unicorn这些依赖,在这里不针对这些一一说明啦,不懂官网上去看吧!不说说的太多啦!
$pnpm add -Dw @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-import eslint-plugin-unicorn --filter=eslint-config-common

在这里插入图片描述

如下是我使用的配置

module.exports = {extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],parser: "@typescript-eslint/parser",plugins: ["@typescript-eslint", "import", "unicorn"],rules: {"arrow-body-style": "off",   // 强制或禁止箭头函数体使用大括号"prefer-arrow-callback": "off", // 要求使用箭头函数作为回调semi: ["error", "always"],     // 半风格-强制一致地使用反引号、双引号或单引号quotes: ["error", "double"], // 引号-强制一致地使用反引号、双引号或单引号eqeqeq: ["error", "always"],  // 需要使用 === 和 !== (消除类型不安全的相等运算符)"object-shorthand": ["error", "always"],"no-sequences": ["error",{allowInParentheses: false}],"prefer-template": "error", // 字符串拼接使用字符串模板而不是+curly: "error", // 确保将块语句包裹在花括号中来防止错误并提高代码清晰度"padding-line-between-statements": ["error",{blankLine: "always",prev: ["function", "class", "const", "let", "var", "block-like"],next: "*"},{blankLine: "always",prev: "*",next: ["return", "block-like"]},{blankLine: "any",prev: ["const", "let", "var"],next: ["const", "let", "var"]}],"padded-blocks": ["error", "never"],"no-unused-vars": "off","@typescript-eslint/no-unused-vars": ["error",{varsIgnorePattern: "^_",argsIgnorePattern: "^_",ignoreRestSiblings: true}],"no-console": "error","no-restricted-imports": ["error",{patterns: [{group: ["~/localization/*"],message: "Don't import any internals from a module, only use its public api"}]}],// 对比排序前后代码,排序后的代码看起来更整洁"import/order": ["error",{groups: ["builtin", "external", "internal", "parent", "sibling", "index"],pathGroups: [{pattern: "~/**",group: "internal",},],alphabetize: {order: "asc",caseInsensitive: true,},"newlines-between": "never",},],"import/named": "error", // 验证所有命名导入是否是引用模块中命名导出集的一部分"import/no-duplicates": "error", // 导入/无重复"import/no-useless-path-segments": [ // 防止在 import 和 require 语句中出现不必要的路径段"error",{noUselessIndex: true,},],"import/newline-after-import": "error", // 顶级导入语句或要求调用之后有一个或多个空行"unicorn/no-for-loop": "error", // 不要使用for,可以用循环替换的for-of循环"unicorn/consistent-function-scoping": "error", // 将函数定义移动到可能的最高范围"unicorn/explicit-length-check": "error", // 强制显式比较值的length or size属性"unicorn/no-array-instanceof": "error", // 需要Array.isArray()而不是instanceof Array"unicorn/prefer-array-find": "error",  // 优先使用.find(…)或.findLast(…)而不是.filter(…)"unicorn/prefer-includes": "error", // 优先使用.includes()而不是.indexOf()"unicorn/prefer-string-slice": "error", // 字符串优先使用String#slice() 而不是 String#substr() 和 String#substring()"unicorn/consistent-destructuring": "error", // 在属性上使用解构变量"unicorn/no-nested-ternary": "error", // 禁止嵌套三元表达式"import/no-default-export": "error",  // 禁用 export default 规则"no-await-in-loop": "off",// 禁止在循环中出现 await"@typescript-eslint/no-explicit-any": "error", // 不允许any类型"no-empty-function": "off",// Note: you must disable the base rule as it can report incorrect errors"@typescript-eslint/no-empty-function": "off"}
}
  • eslint-config-custom 基础项目 eslint 配置,如apps,utils等, 安装 eslint-config-prettier、eslint-plugin-prettier 这些依赖,在这里不针对这些一一说明啦,不懂官网上去看吧!不说说的太多啦!,并集成eslint-config-custom的配置
$pnpm add -Dw eslint-config-prettier eslint-plugin-prettier --filter=eslint-config-custom

在这里插入图片描述

如下是我使用的配置

module.exports = {env: {browser: true,es2021: true,node: true},extends: ["common", "prettier"],overrides: [{files: ["*.config.{ts,js}"],rules: {"import/no-default-export": "off"}}]
}
  • eslint-config-vue vue项目 eslint 配置,校验vue,这里跟官网插件一个名字,不要混交,只是针对官网的eslint-config-vue提取配置, 安装 @vue/eslint-config-prettier,eslint-config-vue 依赖,在这里不针对这些一一说明啦,不懂官网上去看吧!不说说的太多啦!,并集成eslint-config-custom的配置
$pnpm add -Dw @vue/eslint-config-prettier --filter=eslint-config-custom
$pnpm add -w eslint-config-vue --filter=eslint-config-custom

在这里插入图片描述

如下是我使用的配置

module.exports = {root: true,env: { node: true },globals: {defineEmits: "readonly",defineProps: "readonly"},extends: ["common", "plugin:vue/vue3-recommended", "@vue/prettier"],overrides: [{files: ["*.config.{ts,js}"],rules: {"import/no-default-export": "off"}}],parser: "vue-eslint-parser",parserOptions: {parser: "@typescript-eslint/parser",ecmaVersion: 2020},rules: {// 在<template>中强制一致缩进"vue/html-indent": ["error", 2],// "vue/html-indent": ["error", "tab"], // enforce tabs in template// indent: ["error", "tab"], // enforce tabs in script and js files"vue/html-self-closing": "off",// 要求单行元素的内容前后有一个换行符"vue/singleline-html-element-content-newline": "off","vue/multi-word-component-names": ["error",{ignores: ["index"] //需要忽略的组件名},],// 执行自闭合的风格"vue/max-attributes-per-line": ["off",{singleline: 4,multiline: 1}]}
}

到这里项目用的eslint 基本编写的差不多啦!

补充说明:eslint-config-common 忘记配置turbo 的插件啦,在这里安装下,

$pnpm add -Dw eslint-config-turbo --filter=eslint-config-common
// index.js 补充
module.exports = {extends: ["turbo", "eslint:recommended", "plugin:@typescript-eslint/recommended"],....
}

安装prettier

prettier 并没有提供太多的配置选项给我们选择,但是相对上面的eslint,更简单更温和一点,我们根据自己的喜好做一个适合自己的配置就行。prettier官网

  $pnpm add  prettier -Dw

prettier 一些常用的配置,如下配置中基本都是默认值

   printWidth: 80, //单行长度tabWidth: 2, //缩进长度useTabs: false, //使用空格代替tab缩进semi: true, //句末使用分号singleQuote: true, //使用单引号quoteProps: 'as-needed', //仅在必需时为对象的key添加引号jsxSingleQuote: true, // jsx中使用单引号trailingComma: 'all', //多行时尽可能打印尾随逗号bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar }jsxBracketSameLine: true, //多属性html标签的‘>’折行放置arrowParens: 'always', //单参数箭头函数参数周围使用圆括号-eg: (x) => xrequirePragma: false, //无需顶部注释即可格式化insertPragma: false, //在已被preitter格式化的文件顶部加上标注proseWrap: 'preserve', //不知道怎么翻译htmlWhitespaceSensitivity: 'ignore', //对HTML全局空白不敏感vueIndentScriptAndStyle: false, //不对vue中的script及style标签缩进endOfLine: 'lf', //结束行形式embeddedLanguageFormatting: 'auto', //对引用代码进行格式化

tips: 这个是在线的格式配置信息,可以在上面配置好直接复制到项目中,点击这里

如下是我此次的初次配置,后面根据需要慢慢补充

{"printWidth": 120,"tabWidth": 2,"useTabs": false,"semi": false,"singleQuote": true,"quoteProps": "consistent","jsxSingleQuote": false,"trailingComma": "none","bracketSpacing": true,"jsxBracketSameLine": false,"htmlWhitespaceSensitivity": "css","proseWrap": "preserve"
}

测试 prettier命令, 在package.json的 scripts 里加入 “format”: “turbo run prettier --write .”

...."scripts": {"format": "prettier --write ."...

然后控制台运行 pnpm run format, 如下

在这里插入图片描述

测试一切正常,然后优化,加入的 lint-staged里, 去掉 scripts的format,最终 package.json如下

{"name": "robin-design","private": true,"version": "1.0.0","description": "robin-design","type": "module","scripts": {"preinstall": "npx only-allow pnpm","prepare": "husky"},"workspaces": ["apps/*","packages/*"],"keywords": [],"author": "wanglb","license": "MIT","packageManager": "pnpm@8.15.0","engines": {"pnpm": ">=8.0"},"lint-staged": {"**/*.{js,jsx,ts,tsx,vue,json,css,less,md}": ["prettier --write ."]},"devDependencies": {"eslint": "^8.56.0","eslint-config-common": "workspace:*","husky": "^9.0.10","lint-staged": "^15.2.1","prettier": "^3.2.4"}
}

配置 .editorconfig

用来帮助开发者定义和维护代码风格的。但是它与 Prettier 不同的是,Prettier 是 JS 特有的格式化工具,里面有很多配置项是 JS 语言特有的规范,而 editorconfig 适应性更广泛,它可以跨编辑器(或 )维护统一的代码风格,专注于比较基础的格式化,比如 Tab 缩进、文件编码、末尾换行符等,这些规范与使用哪种编程语言无关。官网地址

root = true                         # 根目录的配置文件,编辑器会由当前目录向上查找,如果找到 `roor = true` 的文件,则不再查找
​
[*]
indent_style = space                # 空格缩进,可选"space""tab"
indent_size = 2                     # 缩进空格为4个
end_of_line = lf                    # 结尾换行符,可选"lf""cr""crlf"
charset = utf-8                     # 文件编码是 utf-8
trim_trailing_whitespace = true     # 不保留行末的空格
insert_final_newline = true         # 文件末尾添加一个空行
curly_bracket_next_line = false     # 大括号不另起一行
spaces_around_operators = true      # 运算符两遍都有空格
indent_brace_style = 1tbs           # 条件语句格式是 1tbs
​
[*.js]                              # 对所有的 js 文件生效
quote_type = single                 # 字符串使用单引号
​
[*.{html,less,css,json}]            # 对所有 html, less, css, json 文件生效
quote_type = double                 # 字符串使用双引号
​
[package.json]                      # 对 package.json 生效
indent_size = 4                   # 使用2个空格缩进

如下是我此次的初次配置,后面根据需要慢慢补充

# http://editorconfig.org
root = true[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true[package.json]
indent_size = 2

配置 .gitignore

没啥好说的,只要不想提交的,一股脑加进去

# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.# dependencies
node_modules
.pnp
.pnp.js# testing
coverage# build
dist# misc
.DS_Store
*.pem# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local# turbo
.turbo# orther
.vscode
.husky

初步项目结构

robin-design                                    // husky 钩子配置目录
├─ .editorconfig                                // 编辑器配置
├─ .git                                         // git初始换信息
├─ .gitignore                                   // git 排除文件
├─ .husky                                       // husky 钩子配置目录
│  ├─ commit-msg                                // 校验提交信息
│  ├─ pre-commit                                // 提交之前验证
│  └─ _
├─ .prettierrc                                  // 格式化配置
├─ apps                                         // 应用目录
├─ package.json
├─ packages                                     // 系统通用包
│  ├─ eslint-config-common                      // 公共 eslint rules 配置
│  │  ├─ index.js
│  │  └─ package.json
│  ├─ eslint-config-custom                      // 基础项目 eslint 配置
│  │  ├─ index.js
│  │  └─ package.json
│  └─ eslint-config-vue                         // 基础 eslint vue 配置
│     ├─ index.js
│     └─ package.json
├─ pnpm-lock.yaml
├─ pnpm-workspace.yaml
├─ README.md
└─ turbo.json                                   // turbo repo 配置文件

结语

本文从实战出发,初步单间一个为 turbo的基础项目工程项目,本文我估计,是全网唯一一个手把手第一次真正从0到一的完整的教程,纯属个人见解,因为我没有看到像我这么全的!,本文旨意在搭建一个vue3的组件库,后面还有更多的文章信息,我也不知道后面文章什么时候更新,本人很赖!希望大家鼓励鼓励我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/688634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSTI模板注入漏洞(vulhub 复现)

首先了解模板引擎&#xff1a; 模板引擎&#xff08;这里特指用于Web开发的模板引擎&#xff09;是为了使用户界面与业务数据&#xff08;内容&#xff09;分离而产生的&#xff0c;它可以生成特定格式的文档&#xff0c;利用模板引擎来生成前端的html代码&#xff0c;模板引擎…

网络原理 - HTTP/HTTPS(1)

HTTP HTTP是什么 HTTP("全程超文本协议")是一种应用非常广泛的应用层协议. 文本:字符串(能在utf8/gbk)码表上找到合法字符. 超文本:不仅是字符串,还能携带图片啥的(HTML). 富文本:类似于word文档这种. HTTP诞生于1991年.目前已经发展为最主流使用的一种应用层协议.…

如何使用python 挑战将ai生成的概念图制作成2d游戏

要使用Python将AI生成的概念图制作成2D游戏&#xff0c;你可以遵循以下步骤&#xff1a; 生成概念图&#xff1a; 使用AI图像生成工具&#xff08;如DALL-E、DeepArt等&#xff09;来创建你的游戏概念图。保存生成的图像文件&#xff0c;通常为PNG或JPEG格式。 选择游戏引擎&a…

防火墙 iptables(二)-------------SNAT与DNAT

一、SNAT ①SNAT 应用环境: 局域网主机共享单个公网IP地址接入Internet (私有IP不能在Internet中正常路由) ②SNAT原理: 源地址转换&#xff0c;根据指定条件修改数据包的源IP地址&#xff0c;通常被叫做源映射 数据包从内网发送到公网时&#xff0c;SNAT会把数据包的源IP由…

【Java EE初阶十九】网络原理(四)

4. 数据链路层 数据链路层也有很多种协议&#xff0c;其中一个比较常见常用的,就是“以太网协议”&#xff08;通过网线/光纤, 来通信所使用的协议叫做以太网协议&#xff0c;以太网是横跨数据链路层 物理层&#xff09;&#xff1b; 4.1 以太网数据帧格式 帧头 载荷(IP 数据…

从一到无穷大 #24 LogReducer:讨论日志中热点的影响,识别及在线解决方法

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言LogReducer系统性分析日志影响&#xff0c;原因在线日志缩减框架 反省总结 引言 …

提升起重机效率与降低维修成本:PreMaint预测性维护系统的应用

随着科技的不断发展&#xff0c;人工智能技术在各行各业都展现出了强大的应用潜力。在港口起重机设备的维护管理中&#xff0c;预测性维护系统是一项革命性的技术&#xff0c;为提升设备效率、降低维修成本提供了全新的解决方案。本文将深入探讨起重机预测性维护系统的原理、应…

nvm的相关属性以及用法

一、安装nvm的原因 nvm是一个命令行工具&#xff0c;用于管理和切换到不同版本的 Node.js。 二、安装nvm&#xff08;node 版本管理工具&#xff09; 1、注意&#xff1a; Windows 不支持 NVM&#xff0c;因为 NVM 仅在 Linux 和 Mac 上受支持。你将在 Windows 机器上使用的…

中小品牌项目管理软件排行榜:发现行业新秀与潜力股

使用项目管理软件可以帮助企业提高工作效率&#xff0c;降低成本&#xff0c;提升竞争力。在项目管理软件中&#xff0c;不仅有大品牌如Zoho Projects、Microsoft Project、Jira等&#xff0c;还有一些小品牌的软件也备受关注。本文就为大家介绍在项目管理软件排行榜中小品牌榜…

09_Java集合

一、Java集合框架概述 一方面&#xff0c; 面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象的操作&#xff0c;就要对对象进行存储。另一方面&#xff0c;使用Array存储对象方面具有一些弊端&#xff0c;而Java 集合就像一种容器&#xff0c;可以动态…

如何在Linux系统中配置并优化硬盘的RAID

在Linux系统中配置和优化硬盘的RAID技术可以帮助提高数据存储性能和安全性。RAID&#xff08;Redundant Array of Independent Disks&#xff09;技术通过将多个硬盘组合起来&#xff0c;以增加性能、容量或冗余度&#xff0c;提高数据的可靠性和可用性。本文将介绍如何在Linux…

6.s081 学习实验记录(十)file system

文章目录 一、Large files简介提示实验代码实验结果 二、Symbolic links简介提示实验代码实验结果 首先切换到 fs 分支 $ git fetch$ git checkout fs$ make clean 一、Large files 简介 该实验需要我们增大xv6文件的最大大小&#xff0c;目前xv6的最大文件大小为 268个块&…

WordPress主题YIA在广告位添加图片广告时下方有空白怎么办?

YIA主题设置中默认有4个广告位&#xff0c;而侧边栏的广告位由站长自行添加。boke112百科在这些广告位添加图片广告后发现图片下方有空白&#xff0c;导致下方的两个角没有变圆角&#xff0c;看起来也有点不好看。具体如下图所示&#xff1a; 其实&#xff0c;这个问题就是典型…

挑战杯 地铁大数据客流分析系统 设计与实现

文章目录 1 前言1.1 实现目的 2 数据集2.2 数据集概况2.3 数据字段 3 实现效果3.1 地铁数据整体概况3.2 平均指标3.3 地铁2018年9月开通运营的线路3.4 客流量相关统计3.4.1 线路客流量排行3.4.2 站点客流量排行3.4.3 入站客流排行3.4.4 整体客流随时间变化趋势3.4.5 不同线路客…

跟着pink老师前端入门教程(JavaScript)-day01

一、计算机编程基础 &#xff08;一&#xff09;编程语言 1、编程 编程&#xff1a;就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码&#xff0c;并最终得到结果的过程。 计算机程序&#xff1a;就是计算机所执行的一系列的指令集合&#xff0c;而程序全部…

嵌入式学习 C++ Day5、6

嵌入式学习 C Day5、6 一、思维导图 二、作业 1.以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴…

UVa1359/LA3491 Hills

题目链接 本题是2005年ICPC亚洲区域赛杭州欧赛区的H题 题意 平面上有 n&#xff08;n≤500&#xff09;条线段&#xff0c;其中每条线段的端点都不会在其他线段上。你的任务是数一数有多少个“没有被其他线段切到”的三角形&#xff08;即小山&#xff09;。如下图所示&#x…

【Vitis】Vitis性能优化的开源库

Vitis HLS简介 Vitis™HLS是一种高层次综合工具&#xff0c;支持将C、C和OpenCL™函数硬连线到器件逻辑互连结构和RAM/DSP块上。 Vitis HLS可在Vitis应用加速开发流程中实现硬件内核&#xff0c;并使用C/C语言代码在VivadoDesign Suite中为赛灵思器件设计开发RTL IP。 【Vitis…

不坑盒子 助力高效办公的Office插件

不坑盒子简介 很多朋友在工作过程中需要对Word文档进行编辑处理&#xff0c;如果想让Word排版更有效率可以试试小编带来的这款不坑盒子软件&#xff0c;是一个非常好用的办公工具&#xff0c;拥有近百项功能的Word&#xff0c;wps插件&#xff0c;支持Office 2010以上的版本&a…

【plt.bar绘制条形图or柱状图】:从入门到精通,只需一篇文章!【Matplotlib可视化】

【&#x1f4ca;plt.bar绘制条形图】&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;【Matplotlib】 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; &#x1f50d; 一、初识plt.bar&#xff1a;条形图的基本概念&#x1f4a1; 二、plt.…