理解按需自动导入 unplugin-auto-import unplugin-vue-components

news2024/12/27 10:35:52

在这里插入图片描述

文章目录

  • unplugin-auto-import
    • 基础使用
      • 构建工具引入插件
      • 配置插件
    • import:配置自动导入规则
      • 使用预设
      • 自动引入第三方库
      • 自动导入 TypeScript 类型
      • vue 预设的自动导入配置
    • dts:让编辑器环境识别 ts 类型
    • eslintrc:解决 eslint 检查错误
    • dirs:配置本地目录文件自动导入
  • unplugin-vue-components
    • 基本使用
    • 导入流行库组件
    • 自动引入自己的本地组件
    • 自定义解析器 resolvers,实现组件库按需导入
    • 开源库的解析器写法(参考)
      • element-plus
      • vant

unplugin-auto-import

Auto import APIs on-demand for Vite, Webpack, Rspack, Rollup and esbuild. With TypeScript support. Powered by unplugin.

基础使用

项目中的 js 模块可以使用 unplugin-auto-import 来自动引入。

比如 vue 的一些 api,ref,reactive 等,可以不用手动导入。但要明白插件只是帮助我们在编译时自动添加 import,而不是代码中可以没有 import 导入。

看看 element-plus 的自动引入配置:

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

export default defineConfig(({ command }) => {
    return {
        plugins: [
            vue(),
            AutoImport({
                resolvers: [ElementPlusResolver({ importStyle: "sass" })],
                eslintrc: {
                    enabled: true
                }
            }),
            Components({
                resolvers: [ElementPlusResolver({ importStyle: "sass" })]
            })
          ]
    }
}

安装:

pnpm i -D unplugin-auto-import

构建工具引入插件

因为上面是 vite 中使用,因此引入 unplugin-vue-components 的 vite 插件版本unplugin-vue-components/vite

其他常见构建工具引入:webpack、vue cli

// webpack.config.js & vue.config.js
module.exports = {
  /* ... */
  plugins: [
    require('unplugin-auto-import/webpack').default({ /* options */ }),
  ],
}

配置插件

AutoImport({
  // targets to transform
  include: [
    /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
    /\.vue$/,
    /\.vue\?vue/, // .vue
    /\.md$/, // .md
  ],

  // global imports to register
  imports: [
    // presets
    'vue',
    'vue-router',
    // custom
    {
      '@vueuse/core': [
        // named imports
        'useMouse', // import { useMouse } from '@vueuse/core',
        // alias
        ['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core',
      ],
      'axios': [
        // default imports
        ['default', 'axios'], // import { default as axios } from 'axios',
      ],
      '[package-name]': [
        '[import-names]',
        // alias
        ['[from]', '[alias]'],
      ],
    },
    // example type import
    {
      from: 'vue-router',
      imports: ['RouteLocationRaw'],
      type: true,
    },
  ],
  // Enable auto import by filename for default module exports under directories
  defaultExportByFilename: false,

  // Auto import for module exports under directories
  // by default it only scan one level of modules under the directory
  dirs: [
    // './hooks',
    // './composables' // only root modules
    // './composables/**', // all nested modules
    // ...
  ],

  // Filepath to generate corresponding .d.ts file.
  // Defaults to './auto-imports.d.ts' when `typescript` is installed locally.
  // Set `false` to disable.
  dts: './auto-imports.d.ts',

  // Auto import inside Vue template
  // see https://github.com/unjs/unimport/pull/15 and https://github.com/unjs/unimport/pull/72
  vueTemplate: false,

  // Custom resolvers, compatible with `unplugin-vue-components`
  // see https://github.com/antfu/unplugin-auto-import/pull/23/
  resolvers: [
    /* ... */
  ],

  // Inject the imports at the end of other imports
  injectAtEnd: true,

  // Generate corresponding .eslintrc-auto-import.json file.
  // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
  eslintrc: {
    enabled: false, // Default `false`
    filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
    globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
  },
})

上面的配置很完整,但我们一般关注其中几个就可以了。

import:配置自动导入规则

使用预设

对于一些常见的库,插件已经内置了它的自动导入规则,如:vue、vue-router、pinia、react 等。

在 imports 数组里添加字符串就代表使用预设:

AutoImport({
  imports: ["vue", "vue-router", "pinia"],
}

自动引入第三方库

有些库没有预设,我们也想自动导入该怎么办?比如 axios、loadsh、vueuse。

使用对象语法,自定义导入规则:包名: 数组

AutoImport({
  imports: [
    "vue",
    // 自定义导入规则
    {
      '包名 ikun': [
        // 命名导入,相当于会自动添加 import { sing } from "ikun";
        'sing',
        // 设置别名导入,自动添加 import { sing as singFromIkun } from "ikun";
        ['sing', 'singFromIkun'],
      ],
    },
  ]
})

注意:对于默认导出的库,export default,自定义导入规则要写成别名导入的形式,导入的字段为 default。

比如 axios,我们正常使用是这样导入:

import axios from "axios"

因为 axios 库是 export default 默认导出的,所以我们不会 import { axios } from "axios";
对于这种默认导出,AutoImport 自动导入规则要写成别名导入:

AutoImport({
  imports: [
    "vue",
    // 自定义导入规则
    {
      '包名 ikun': [
        // 命名导入,相当于会自动添加 import { sing } from "ikun";
        'sing',
        // 设置别名导入,自动添加 import { sing as singFromIkun } from "ikun";
        ['sing', 'singFromIkun'],
      ],
      'axios': [
        // default imports
        ['default', 'axios'], // import { default as axios } from 'axios',
      ],
    },
  ]
})

说白了,压根没有import axios from "axios";的写法,它只是import { default as axios} from "axios";的语法糖。因此在这种编译配置的情况下,需要严格按照规范来定义。

补充一个自动导入 vueuse:

AutoImport({
  imports: [
    "vue",
    {
      '@vueuse/core': [
        // named imports
        'useMouse', // import { useMouse } from '@vueuse/core',
        // alias
        ['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core',
      ]
    }
  ]
})

自动导入 TypeScript 类型

上面都是 js 引入,如果是在 ts 中这样引入,会没有类型,vue-tsc 类型检查过不了,build 构建失败。

导入 ts 类型的规则:

{
  from: 'vue-router',
  imports: ['RouteLocationRaw'],
  type: true,
}

其实上面这种写法才是导入规则的完整写法包名: 数组字符串这些都是简写,就和 webpack loader 配置一样。
这个对象就是在模拟import { xxx } from "xxx";,多了一个 type 为 true,就是标明了导入的为类型,等价于:import type { Xxx as Hhh} from "xxx";

这时候就要注意 type 的位置了:

AutoImport({
  imports: [
    "vue",
    // {
    //     axios: ["default", "axios"]
    // },
    {
      from: "axios",
      imports: [["default", "axios"], "AxiosStatic"],
      type: true
    }
  ],
})

如上述写法就是错误的,它编译后就是:

import type { default as axios, AxiosStatic} from "axios";

显然 axios 不是类型,正确写法应该是:

import { default as axios, type AxiosStatic} from "axios";

那怎么把 type 和 AxiosStatic 类型绑定到一起,编译出正确的 import 语句呢?

AxiosStatic 继续写成对象形式即可:

AutoImport({
  imports: [
    // {
    //     axios: ["default", "axios"]
    // },
    // {
    //     from: "axios",
    //     imports: [["default", "axios"], "AxiosStatic"],
    //     type: true
    // }
    {
      from: "axios",
      imports: [ ["default", "axios"], {
          name: "AxiosStatic",
          type: true
        }],
    } 
  ]
})

vue 预设的自动导入配置

可以看到 vue 自动导入配置的预设,内部写法就是如上诉一样:

  • https://github.com/unjs/unimport/blob/main/src/presets/vue.ts
{
     "from": "vue",
     "imports": [
          "EffectScope",
          "computed",
          "createApp",
          "customRef",
          "defineAsyncComponent",
          "defineComponent",
          "effectScope",
          "getCurrentInstance",
          "getCurrentScope",
          "h",
          "inject",
          "isProxy",
          "isReactive",
          "isReadonly",
          "isRef",
          "markRaw",
          "nextTick",
          "onActivated",
          "onBeforeMount",
          "onBeforeUnmount",
          "onBeforeUpdate",
          "onDeactivated",
          "onErrorCaptured",
          "onMounted",
          "onRenderTracked",
          "onRenderTriggered",
          "onScopeDispose",
          "onServerPrefetch",
          "onUnmounted",
          "onUpdated",
          "provide",
          "reactive",
          "readonly",
          "ref",
          "resolveComponent",
          "shallowReactive",
          "shallowReadonly",
          "shallowRef",
          "toRaw",
          "toRef",
          "toRefs",
          "toValue",
          "triggerRef",
          "unref",
          "useAttrs",
          "useCssModule",
          "useCssVars",
          "useSlots",
          "watch",
          "watchEffect",
          "watchPostEffect",
          "watchSyncEffect",
          {
               "name": "Component",
               "type": true
          },
          {
               "name": "ComponentPublicInstance",
               "type": true
          },
          {
               "name": "ComputedRef",
               "type": true
          },
          {
               "name": "ExtractDefaultPropTypes",
               "type": true
          },
          {
               "name": "ExtractPropTypes",
               "type": true
          },
          {
               "name": "ExtractPublicPropTypes",
               "type": true
          },
          {
               "name": "InjectionKey",
               "type": true
          },
          {
               "name": "PropType",
               "type": true
          },
          {
               "name": "Ref",
               "type": true
          },
          {
               "name": "VNode",
               "type": true
          },
          {
               "name": "WritableComputedRef",
               "type": true
          }
     ]
}

dts:让编辑器环境识别 ts 类型

配置 import 后能自动导入 ts 类型了,但那是在编译时才会导入,在 vscode 编辑器里写代码时,类型可没导入。在 ts 看来,你使用了未定义的变量,会报错。

这其实就和之前按需引入 elmessage 的问题一样:
按需引入 ElMessage,没有样式且类型检查失败

这时就需要对自动导入的内容进行类型声明:

AutoImport({
  dts: true // or a custom path
})

开启dts配置后,就会自动生成auto-imports.d.ts文件,进行全局类型声明。默认生成在根目录。
另外要确保tsconfig.json中 include 配置项包含了这个类型声明文件,好让 ts 读取里面的类型。

各种开源组件库按需引入的时候,就默认就打开了这个配置,所以根目录会出现这么个文件。

上面 axios 配置,自动生成的类型声明:

/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
  const axios: typeof import('axios')['default']
}
// for type re-export
declare global {
  // @ts-ignore
  export type { AxiosStatic } from 'axios'
}

eslintrc:解决 eslint 检查错误

ts 通过了禁止使用未定义变量的检查,但 eslint 检查未通过。eslint 的检查中也会认为你使用了未定义的变量。解决办法自然是在 eslint 的配置中声明一下这些是全局变量,可以未导入直接用。

unplugin 官方认为如果使用了 ts,就不必再让 eslint 来检查是否使用未定义的变量了,建议把no-undef这条规则关掉。

💡 When using TypeScript, we recommend to disable no-undef rule directly as TypeScript already check for them and you don’t need to worry about this.

如果开着双重保险,就要让 eslint 识别自动导入的内容为全局变量:

  1. 开启配置,在项目根目录生成全局变量文件 .eslintrc-auto-import.json
AutoImport({
  eslintrc: {
    enabled: true, // <-- this
  },
})
{
  "globals": {
    "AxiosStatic": true,
    "axios": true
  }
}

  1. 在 eslint 校验规则中继承它。
// .eslintrc.js
module.exports = {
  extends: [
    './.eslintrc-auto-import.json',
  ],
}

dirs:配置本地目录文件自动导入

比如项目中有一个 utils 文件夹,如果想自动引入里面的文件,则可以用 dirs 来配置

AutoImport({
 	// Auto import for module exports under directories
  // by default it only scan one level of modules under the directory
  dirs: [
    // './hooks',
    // './composables' // only root modules
    // './composables/**', // all nested modules
    // ...
    "./src/utils/**"
  ]
})

unplugin-vue-components

https://github.com/unplugin/unplugin-vue-components

unplugin-vue-components 这玩意是用来专门引入 vue SFC 文件的,相当于 unplugin-auot-import 的一个子集。作者都是 antfu。

基本使用

// vite.config.ts
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({ /* options */ }),
  ],
})
// webpack.config.js & vue.config.js
module.exports = {
  /* ... */
  plugins: [
    require('unplugin-vue-components/webpack').default({ /* options */ }),
  ],
}
Components({
  // relative paths to the directory to search for components.
  dirs: ['src/components'],

  // valid file extensions for components.
  extensions: ['vue'],

  // Glob patterns to match file names to be detected as components.
  // When specified, the `dirs` and `extensions` options will be ignored.
  globs: ['src/components/*.{vue}'],

  // search for subdirectories
  deep: true,

  // resolvers for custom components
  resolvers: [],

  // generate `components.d.ts` global declarations,
  // also accepts a path for custom filename
  // default: `true` if package typescript is installed
  dts: false,

  // Allow subdirectories as namespace prefix for components.
  directoryAsNamespace: false,

  // Collapse same prefixes (camel-sensitive) of folders and components
  // to prevent duplication inside namespaced component name.
  // works when `directoryAsNamespace: true`
  collapseSamePrefixes: false,

  // Subdirectory paths for ignoring namespace prefixes.
  // works when `directoryAsNamespace: true`
  globalNamespaces: [],

  // auto import for directives
  // default: `true` for Vue 3, `false` for Vue 2
  // Babel is needed to do the transformation for Vue 2, it's disabled by default for performance concerns.
  // To install Babel, run: `npm install -D @babel/parser`
  directives: true,

  // Transform path before resolving
  importPathTransform: v => v,

  // Allow for components to override other components with the same name
  allowOverrides: false,

  // filters for transforming targets
  include: [/\.vue$/, /\.vue\?vue/],
  exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],

  // Vue version of project. It will detect automatically if not specified.
  // Acceptable value: 2 | 2.7 | 3
  version: 2.7,

  // Only provide types of components in library (registered globally)
  types: []
})

导入流行库组件

该插件内置了大多数流行库解析器,可以直接开箱即用。
并且会在根目录生成一个ui库组件以及指令路径components.d.ts文件

// vite.config.js
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import {
  ElementPlusResolver,
  AntDesignVueResolver,
  VantResolver,
  HeadlessUiResolver,
  ElementUiResolver
} from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Components({
      // ui库解析器,也可以自定义
      resolvers: [
        ElementPlusResolver(),
        AntDesignVueResolver(),
        VantResolver(),
        HeadlessUiResolver(),
        ElementUiResolver()
      ]
    })
  ]
})

/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}

declare module 'vue' {
  export interface GlobalComponents {
    ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
    AButton: typeof import('ant-design-vue/es')['Button']
    RouterLink: typeof import('vue-router')['RouterLink']
    RouterView: typeof import('vue-router')['RouterView']
    SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default']
    SwitchTheme: typeof import('./src/components/SwitchTheme/SwitchTheme.vue')['default']
  }
}

自动引入自己的本地组件

默认情况下,自己写的组件放在src/components路径下是会被自动引入的。
比如上面 components.d.ts 文件中的 SvgIcon 和 SwitchTheme 就是自己写的组件。

当然,也可以进一步配置自动引入的情况:

// vite.config.js
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({
      // 指定组件位置,默认是src/components
      dirs: ['src/components'],
      // ui库解析器
      // resolvers: [ElementPlusResolver()],
      extensions: ['vue'],
      // 配置文件生成位置
      dts: 'src/components.d.ts'
    })
  ]
})

自定义解析器 resolvers,实现组件库按需导入

如果是自己开发的组件库,为了让它支持自动按需导入,就需要自己编写解析器。

Components({
  resolvers: [
    // example of importing Vant
    (componentName) => {
      // where `componentName` is always CapitalCase
      if (componentName.startsWith('Van'))
        return { name: componentName.slice(3), from: 'vant' }
    },
  ],
})

resolvers 数组里可以传入一个函数,这个函数会在编译时不断执行。
函数接收组件名,并返回一个和 unplugin-auto-import 插件中 imports 配置一样的配置对象,这个对象就是 import 语句的描述对象,最终依据它生成导入语句。

  • 注意:组件名会自动转成大驼峰写法。

因此所谓的解析器,功能就是根据组件名映射成 import 导入语句。

假设组件库的前缀为 ikun,比如按钮组件: ikun-button

  1. 在 SFC 中使用了组件
<!-- 在 SFC 中使用了组件 -->
<ikun-button>按钮</ikun-button>
  1. 解析器中都能拿到大驼峰格式的组件名
const IkunResolver = componentName => {
    console.log(componentName) // IkunButton

    // 组件名有很多,通过前缀过滤出本组件库的组件名
    if (componentName.startsWith("Ikun")) {
        // import 引入规则对象:
        // 等价于 import { IkunButton } from "ikun-ui";
        return {
            name: componentName,
            from: "ikun-ui"
        }
    }
    return null
}
  1. 使用组件库的 resolver
Components({
  resolvers: [
    IkunResolver()
  ],
})

还有一个细节问题:组件库中组件的样式可能是单独一个文件的,不一定在 .vue 文件中。
比如这样:

ikun-button
|
|—— style
|		|—— index.css
|			
|—— index.vue

上面的 import 配置对象写法只会引入 SFC 文件,并不会引入样式文件。

解决办法:副作用配置项。引入组件的副作用是会引入另一个文件,我们让这个文件是样式文件。

  • sideEffects
const IkunResolver = componentName => {
    if (componentName.startsWith("Ikun")) {
        // 等价于:
        // import { IkunButton } from "ikun-ui";
        // import "ikun-ui/ikun-button/style/index.css";
        return {
            name: componentName,
            from: "ikun-ui",
            sideEffects: `ikun-ui/${componentName}/style/index.css`
        }
    }
    return null
}

开源库的解析器写法(参考)

element-plus

// src/core/resolvers/element-plus.ts
function getSideEffectsLegacy(partialName, options) {
  const { importStyle } = options;
  if (!importStyle)
    return;
  if (importStyle === "sass") {
    return [
      "element-plus/packages/theme-chalk/src/base.scss",
      `element-plus/packages/theme-chalk/src/${partialName}.scss`
    ];
  } else if (importStyle === true || importStyle === "css") {
    return [
      "element-plus/lib/theme-chalk/base.css",
      `element-plus/lib/theme-chalk/el-${partialName}.css`
    ];
  }
}
function getSideEffects2(dirName, options) {
  const { importStyle, ssr, nightly } = options;
  const themeFolder = nightly ? "@element-plus/nightly/theme-chalk" : "element-plus/theme-chalk";
  const esComponentsFolder = nightly ? "@element-plus/nightly/es/components" : "element-plus/es/components";
  if (importStyle === "sass") {
    return ssr ? [`${themeFolder}/src/base.scss`, `${themeFolder}/src/${dirName}.scss`] : [`${esComponentsFolder}/base/style/index`, `${esComponentsFolder}/${dirName}/style/index`];
  } else if (importStyle === true || importStyle === "css") {
    return ssr ? [`${themeFolder}/base.css`, `${themeFolder}/el-${dirName}.css`] : [`${esComponentsFolder}/base/style/css`, `${esComponentsFolder}/${dirName}/style/css`];
  }
}
function resolveComponent(name, options) {
  if (options.exclude && name.match(options.exclude))
    return;
  if (!name.match(/^El[A-Z]/))
    return;
  if (name.match(/^ElIcon.+/)) {
    return {
      name: name.replace(/^ElIcon/, ""),
      from: "@element-plus/icons-vue"
    };
  }
  const partialName = kebabCase(name.slice(2));
  const { version, ssr, nightly } = options;
  if (compare(version, "1.1.0-beta.1", ">=") || nightly) {
    return {
      name,
      from: `${nightly ? "@element-plus/nightly" : "element-plus"}/${ssr ? "lib" : "es"}`,
      sideEffects: getSideEffects2(partialName, options)
    };
  } else if (compare(version, "1.0.2-beta.28", ">=")) {
    return {
      from: `element-plus/es/el-${partialName}`,
      sideEffects: getSideEffectsLegacy(partialName, options)
    };
  } else {
    return {
      from: `element-plus/lib/el-${partialName}`,
      sideEffects: getSideEffectsLegacy(partialName, options)
    };
  }
}
function resolveDirective(name, options) {
  if (!options.directives)
    return;
  const directives2 = {
    Loading: { importName: "ElLoadingDirective", styleName: "loading" },
    Popover: { importName: "ElPopoverDirective", styleName: "popover" },
    InfiniteScroll: { importName: "ElInfiniteScroll", styleName: "infinite-scroll" }
  };
  const directive = directives2[name];
  if (!directive)
    return;
  const { version, ssr, nightly } = options;
  if (compare(version, "1.1.0-beta.1", ">=") || nightly) {
    return {
      name: directive.importName,
      from: `${nightly ? "@element-plus/nightly" : "element-plus"}/${ssr ? "lib" : "es"}`,
      sideEffects: getSideEffects2(directive.styleName, options)
    };
  }
}
var noStylesComponents = ["ElAutoResizer"];
function ElementPlusResolver(options = {}) {
  let optionsResolved;
  async function resolveOptions() {
    if (optionsResolved)
      return optionsResolved;
    optionsResolved = __spreadValues({
      ssr: false,
      version: await getPkgVersion("element-plus", "2.2.2"),
      importStyle: "css",
      directives: true,
      exclude: void 0,
      noStylesComponents: options.noStylesComponents || [],
      nightly: false
    }, options);
    return optionsResolved;
  }
  return [
    {
      type: "component",
      resolve: async (name) => {
        const options2 = await resolveOptions();
        if ([...options2.noStylesComponents, ...noStylesComponents].includes(name))
          return resolveComponent(name, __spreadProps(__spreadValues({}, options2), { importStyle: false }));
        else
          return resolveComponent(name, options2);
      }
    },
    {
      type: "directive",
      resolve: async (name) => {
        return resolveDirective(name, await resolveOptions());
      }
    }
  ];
}

vant

// src/core/resolvers/vant.ts
var moduleType = isSSR ? "lib" : "es";
function getSideEffects4(dirName, options) {
  const { importStyle = true } = options;
  if (!importStyle || isSSR)
    return;
  if (importStyle === "less")
    return `vant/${moduleType}/${dirName}/style/less`;
  if (importStyle === "css")
    return `vant/${moduleType}/${dirName}/style/index`;
  return `vant/${moduleType}/${dirName}/style/index`;
}
function VantResolver(options = {}) {
  return {
    type: "component",
    resolve: (name) => {
      if (name.startsWith("Van")) {
        const partialName = name.slice(3);
        return {
          name: partialName,
          from: `vant/${moduleType}`,
          sideEffects: getSideEffects4(kebabCase(partialName), options)
        };
      }
    }
  };
}

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

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

相关文章

AI 论文精读,中文视频讲解:剖析人工智能本质 | 开源日报 No.120

mli/paper-reading Stars: 21.8k License: Apache-2.0 深度学习论文精读是一个深度学习相关论文列表&#xff0c;包括计算机视觉、生成模型、自然语言处理等多个领域。 该项目的核心优势和特点包括&#xff1a; 提供了大量关于深度学习各领域热门文章内容对不同年份发表的有较…

数据类型,运算符,表达式复习

本章没太需要复习的&#xff0c;重点复习一下逗号表达式还有习题吧 总结 表达式1&#xff0c;表达式2 计算的过程为&#xff0c;先算表达式1&#xff0c;再算表达式2&#xff0c;整个表达式的值为表达式2的值 还可以无限套娃&#xff0c;像这样(&#xff08;a&#xff0c;b&…

03-JVM对象创建与内存分配机制深度剖析

文章目录 对象的创建对象创建的主要流程一、类加载检查二、分配内存划分内存的方法解决并发问题的方法 三、初始化零值四、设置对象头五、执行<init>方法 对象半初始化对象大小与指针压缩什么是java对象的指针压缩&#xff1f;为什么要进行指针压缩&#xff1f; 对象内存…

Linux常用的基础命令

一、通配符 1、定义&#xff1a; 有些符号不表示原来的意思&#xff0c;它代表了一类字符 " * "&#xff1a;代表任意长度的字符&#xff0c;不能显示隐藏文件 " ? "&#xff1a;代表任意一个字符 2、作用&#xff1a; 去匹配文件的名字。 例如&am…

『Linux升级路』基础开发工具——gdb篇

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;Linux &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、背景知识介绍 二、gdb指令介绍 一、背景知识介绍 在软件开发中&#xff0c…

用Go语言实现HTTP API的安全验证

HTTP API的安全验证&#xff0c;通常我们会使用诸如OAuth、API密钥、JWT&#xff08;JSON Web Tokens&#xff09;等方法。这里&#xff0c;我将向您展示如何使用JWT在Go语言中实现HTTP API的安全验证。 1. JWT简介 JWT是一种开放标准&#xff08;RFC 7519&#xff09;&#…

软件项目安全保证措施

一、 身份鉴别 二、 访问控制 三、 通信完整性、保密性 四、 抗抵赖 五、 数据完整性 六、 数据保密性 七、 应用安全支撑系统设计 软件开发全流程文档支撑下载&#xff1a;软件项目开发全套文档下载-CSDN博客

VScode 工作区配置 和 用户配置

一、工作区配置 通常不同的项目都有不同的配置&#xff0c;我一般都是使用eslint和prettier一起用&#xff0c;所以经常会有这几个文件&#xff1a; 这里简单介绍一下这几个文件的作用吧。 1.vscode文件夹下 一般有两个文件&#xff0c;extensions.json和settings.json。 e…

基于Java SSM框架实现人事员工考勤签到请假管理系统项目【项目源码+论文说明】

基于java的SSM框架实现人事员工考勤签到请假管理系统演示 摘要 在高速发展的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;人们对人事管理系统越来越重视&#xff0…

Java Web Day06_JQuery基础

课程安排 jQuery是什么 框架&#xff08;framework&#xff09;是一个框子——指其约束性&#xff0c;也是一个架子——指其支撑性。是一个基本概念上的结构&#xff0c;用于去解决或者处理复杂的问题。 jQuery是目前使用最广泛的javascript函数库&#xff0c;极大地简化了ja…

100GPTS计划-AI学术AcademicRefiner

地址 https://chat.openai.com/g/g-LcMl7q6rk-academic-refiner https://poe.com/AcademicRefiner 测试 减少相似性 增加独特性 修改http://t.csdnimg.cn/jyHwo这篇文章微调 专注于人工智能、科技、金融和医学领域的学术论文改写&#xff0c;秉承严格的专业和学术标准。 …

华为OD机试 - 发广播 - 并查集(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、并查集Java 实现并查集 五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&…

机器学习算法(11)——集成技术(Boosting——梯度提升)

一、说明 在在这篇文章中&#xff0c;我们学习了另一种称为梯度增强的集成技术。这是我在机器学习算法集成技术文章系列中与bagging一起介绍的一种增强技术。我还讨论了随机森林和 AdaBoost 算法。但在这里我们讨论的是梯度提升&#xff0c;在我们深入研究梯度提升之前&#xf…

【算法设计与分析】——动态规划算法

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

OpenAI公布ChatGPT安全框架

12月19日&#xff0c;OpenAI在官网公布了“准备框架”&#xff08;Preparedness Framework&#xff09;测试版。该文档详细介绍了OpenAI是如何保证ChatGPT等产品的安全防护措施、开发和部署流程。 OpenAI表示&#xff0c;随着大模型的功能迭代不断完善&#xff0c;其能力已经开…

Diss一下ApiPost国产软件

如图所示&#xff0c;我用ApiPost和PostMan调用同一个接口同样的参数。 后端返回的数字是20231204183521830&#xff0c;在ApiPost中却变成了20231204183521832。不能理解为什么数字会2 。 而PostMan这边返回的值是正确的。 看来ApiPost确实是遥遥领先了

30. MVC设计模式

JavaEE 开发流程 ↓MVC的概念 MVC是Model-View-Controller的简称&#xff0c;即模型-视图-控制器。 MVC是一种设计模式&#xff0c;它把应用程序分成三个核心模块&#xff1a;模型、视图、控制器&#xff0c;它们各自处理自己的任务。 模型(model) 模型是应用程序的主体部分…

本地使用 docker 运行OpenSearch + Dashboard + IK 分词插件

准备基础镜像 注意一定要拉取和当前 IK 分词插件版本一致的 OpenSearch 镜像: https://github.com/aparo/opensearch-analysis-ik/releases 写这篇文章的时候 IK 最新版本 2.11.0, 而 dockerhub 上 OpenSearch 最新版是 2.11.1 如果版本不匹配的话是不能用的, 小版本号对不上…

Python---TCP 客户端程序开发

1. 开发 TCP 客户端程序开发步骤回顾 创建客户端套接字对象和服务端套接字建立连接发送数据接收数据关闭客户端套接字 2. socket 类的介绍 导入 socket 模块 import socket 创建客户端 socket 对象 socket.socket(AddressFamily, Type) 参数说明: AddressFamily 表示IP地…

SpringBoot 3.2.0实战

SpringBoot 3.2.0实战 1. 关键知识点2. 后端开发(SpringBoot 3.2.0)2.1 接口实现的三大步2.2 参数校验2.3 登录认证2.4 获取用户信息2.5 更新用户基本信息2.6 更新用户头像2.7 更新用户密码 3. 前端开发&#xff08;Vue3Element-Plus)3.1 前置知识3.2 常用指令3.2.1 v-for3.2.2…