Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
"typings": "dist/es/packages/nutui.react.build.d.ts",
"sideEffects": [
"*.scss",
"dist/es/**/style/*",
"dist/cjs/**/style/*",
"dist/style.css",
"dist/styles/font/*",
"dist/styles/font-jmapp/*"
"dist/es/**/style{,-jmapp,-jrkf}/*",
"dist/cjs/**/style{,-jmapp,-jrkf}/*",
"dist/style{,-jmapp,-jrkf}.css",
"dist/styles/**/*",
"dist/styles/font{,-jmapp,-jrkf}/*"
],
"description": "京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序",
"keywords": [
Expand Down
42 changes: 35 additions & 7 deletions packages/nutui-templates/create-app-demo/craco.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
module.exports = {
webpack: {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: "sass-loader",
options: {
additionalData: `@import '@nutui/nutui-react/dist/styles/variables.scss';`
// JDesign 主题
// additionalData: `@import '@nutui/nutui-react/dist/styles/variables-jmapp.scss';`
// JRKF 主题
// additionalData: `@import '@nutui/nutui-react/dist/styles/variables-jrkf.scss';`
},
},
],
},
],
},
},
babel: {
plugins: [
[
"import",
'import',
{
"libraryName": "@nutui/nutui-react",
"libraryDirectory": "dist/esm",
"style": "css",
"camel2DashComponentName": false
libraryName: '@nutui/nutui-react',
camel2DashComponentName: false,
customName: (name, file) => {
return `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}`
},
// 自动加载 scss 样式文件
customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

出来 taro了

// 自动加载 css 样式文件
// customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
},
"nutui-react"
]
'nutui-react',
],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

更新Babel插件配置

babel-plugin-import配置已更新,使用动态的customName和customStyleName函数来解析组件路径和样式路径,支持按需加载组件样式。

但在38-39行中,注释表示是"自动加载css样式文件",而实际路径与36行的SCSS路径相同,这可能会造成混淆。建议修正这个注释或路径,确保CSS样式文件的正确路径。

-          // 自动加载 css 样式文件
-          // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
+          // 自动加载 css 样式文件
+          // customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style/css`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'import',
{
"libraryName": "@nutui/nutui-react",
"libraryDirectory": "dist/esm",
"style": "css",
"camel2DashComponentName": false
libraryName: '@nutui/nutui-react',
camel2DashComponentName: false,
customName: (name, file) => {
return `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}`
},
// 自动加载 scss 样式文件
customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
// 自动加载 css 样式文件
// customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
},
"nutui-react"
]
'nutui-react',
],
'import',
{
libraryName: '@nutui/nutui-react',
camel2DashComponentName: false,
customName: (name, file) => {
return `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}`
},
// 自动加载 scss 样式文件
customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style`
// 自动加载 css 样式文件
// customStyleName: (name) => `@nutui/nutui-react-taro/dist/es/packages/${name.toLowerCase()}/style/css`
},
'nutui-react',
],

]
},
};
4 changes: 0 additions & 4 deletions packages/nutui-templates/create-app-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
"test": "craco build"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
Expand Down
3 changes: 3 additions & 0 deletions packages/nutui-templates/create-app-demo/src/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import React from 'react'
import '@nutui/nutui-react/dist/styles/themes/default.css'
// import '@nutui/nutui-react/dist/styles/themes/jmapp.css'
// import '@nutui/nutui-react/dist/styles/themes/jrkf.css'
import './App.css'
import { Star } from '@nutui/icons-react'
import { Row, Col, Image, Button } from '@nutui/nutui-react'
Expand Down
7 changes: 4 additions & 3 deletions packages/nutui-templates/vite-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.4",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"typescript": "^5.0.2",
"vite": "^4.4.5",
"sass-embedded": "^1.86.3",
"typescript": "~5.6.2",
"vite": "^6.0.5",
Comment on lines +27 to +29
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

更新和添加依赖以支持多主题构建

添加了sass-embedded依赖并更新了TypeScript和Vite版本,以支持多主题CSS文件的构建和处理。这些更新对于实现主题变量的预处理和动态样式路径解析非常必要。

请确认这些依赖版本是否与项目中的其他模块兼容,特别是升级到Vite 6可能需要确保所有插件都支持新版本。


🏁 Script executed:

#!/bin/bash
# 检查项目中Vite相关的依赖版本
npm ls | grep vite

Length of output: 10386


请更新 Vite 相关插件以支持 Vite 6 版本

packages/nutui-templates/vite-demo/package.json 中已将 Vite 升级至 ^6.0.5,但通过 npm ls | grep vite 验证发现项目实际安装的 Vite 版本仍为 5.4.11,并且存在多项未满足依赖,可能导致构建失败或插件不兼容:

  • @vitejs/plugin-react@^4.2.1
  • @vitest/coverage-v8@^2.0.4
  • @vitest/ui@^2.0.4
  • [email protected]
  • vitest-canvas-mock@^0.3.3

请针对以下几点进行修正:

  • 同步升级上述插件至支持 Vite 6 的最新版本;
  • 或者回退 Vite 版本至与现有插件兼容的范围(如 ^5.x);
  • 最后重新验证 npm ls | grep vite,确保无 UNMET DEPENDENCY 报错。

"vite-plugin-imp": "^2.4.0"
}
}
3 changes: 3 additions & 0 deletions packages/nutui-templates/vite-demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import './App.css'
import { Star } from '@nutui/icons-react'
import { Row, Col, Image, Button } from '@nutui/nutui-react'
import '@nutui/nutui-react/dist/styles/themes/default.css'
// import '@nutui/nutui-react/dist/styles/themes/jmapp.css'
// import '@nutui/nutui-react/dist/styles/themes/jrkf.css'

const Home = () => {
return (
Expand Down
22 changes: 17 additions & 5 deletions packages/nutui-templates/vite-demo/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import vitePluginImp from 'vite-plugin-imp'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
Expand All @@ -11,12 +11,24 @@ export default defineConfig({
{
libName: '@nutui/nutui-react',
style: (name) => {
return `@nutui/nutui-react/dist/esm/${name}/style/css`
return `@nutui/nutui-react/dist/es/packages/${name.toLowerCase()}/style/index`
// return `@nutui/nutui-react/dist/es/packages/${name.toLowerCase()}/style-jmapp/index`
// return `@nutui/nutui-react/dist/es/packages/${name.toLowerCase()}/style-jmapp/index`
},
replaceOldImport: false,
camel2DashComponentName: false,
}
]
})
},
],
}),
],
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler', // 或 "modern","legacy"
additionalData: `@import '@nutui/nutui-react/dist/styles/variables.scss';`
// jmapp 需要在 app 入口引入 import '@nutui/nutui-react/dist/styles/themes/jmapp.css'
// additionalData: `@import '@nutui/nutui-react/dist/styles/variables-jmapp.scss';`
}
}
},
})
119 changes: 77 additions & 42 deletions scripts/build-taro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -244,26 +244,28 @@ async function buildUMD() {
})
}

async function buildAllCSS() {
// 针对不同主题构建全量的 style
async function buildAllCSS(themeName = '') {
// 拷贝styles
const themeStylePath = themeName ? `style-${themeName}` : 'style'
async function generateAllStyles() {
const projectID = process.env.VITE_APP_PROJECT_ID
const content = [
`@import './styles/variables${projectID ? `-${projectID}` : ''}.scss';`,
`@import './styles/variables${themeName ? `-${themeName}` : ''}.scss';`,
`@import './styles/mixins/index.scss';`,
`@import './styles/animation/index.scss';`,
]
const scssFiles = await glob([`${dist}/es/packages/**/*.scss`])
const scssFiles = await glob([`${dist}/es/packages/**/${themeStylePath}/*.scss`])
scssFiles.forEach((file) => {
content.push(
`@import '${relativePath('/' + file, `/${dist}/style.scss`)}';`,
`@import '${relativePath('/' + file, `/${dist}/${themeStylePath}.scss`)}';`,
)
})
dest(`${dist}/style.scss`, content.join('\n'))
await dest(`${dist}/${themeStylePath}.scss`, content.join('\n'))
}

await generateAllStyles()
await vite.build({
configFile: false,
logLevel: 'error',
resolve: {
alias: [{ find: '@', replacement: resolve(__dirname, '../src') }],
Expand All @@ -272,11 +274,16 @@ async function buildAllCSS() {
emptyOutDir: false,
outDir: dist,
lib: {
entry: `./${dist}/style.scss`,
entry: `./${dist}/${themeStylePath}.scss`,
formats: ['es'],
name: 'style',
fileName: 'style',
},
rollupOptions: {
output: {
assetFileNames: `${themeStylePath}.css`, // 资源文件名
}
}
},
})
}
Expand All @@ -287,6 +294,11 @@ async function buildThemeCSS() {
})
const projectID = process.env.VITE_APP_PROJECT_ID
const inputFiles = {}
// nuitui 官方包包含全部主题文件,包括:
// default.css 默认明亮主题
// dark.css 默认暗黑主题
// jmapp.css、jrkf.css 主题
// 例如:jmapp 包只包含 jmapp 的主题文件,且是默认主题文件。
files.forEach(filePath => {
const themeName = basename(filePath, 'scss').replace('theme-', '')
if (!projectID) {
Expand Down Expand Up @@ -331,16 +343,16 @@ async function copyStyles() {
}

// 构建样式
async function buildCSS(p) {
const cssFiles = await glob(['src/packages/**/*.scss'], {
async function buildCSS(themeName = '') {
const componentScssFiles = await glob(['src/packages/**/*.scss'], {
Comment on lines 345 to +347
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

在 Sass 编译过程中添加错误处理日志。

当前仅调用 sass.compileString 进行编译,一旦出现语法错误或找不到依赖,将会直接报错并中断构建,难以及时追踪问题所在。建议在此处捕获异常并输出日志或警告信息,以便追溯问题。

ignore: ['src/packages/**/demo.scss'],
})

const variables = await readFile(
join(__dirname, '../src/styles/variables.scss'),
join(__dirname, `../src/styles/variables${themeName ? `-${themeName}` : ''}.scss`),
)
for (const file of cssFiles) {
const button = await readFile(join(__dirname, '../', file), {
for (const file of componentScssFiles) {
const scssContent = await readFile(join(__dirname, '../', file), {
encoding: 'utf8',
})
// countup 是特例
Expand All @@ -350,30 +362,11 @@ async function buildCSS(p) {
'../src/packages',
base.replace('.scss', ''),
)
const code = sass.compileString(variables + '\n' + button, {
loadPaths: [loadPath],
})
const cssPath = relative('src', loadPath)
// 写 css 文件
await dest(join(`${dist}/es`, cssPath, 'style/style.css'), code.css)
await dest(join(`${dist}/es`, cssPath, 'style/css.js'), `import './style.css'`)

await dest(join(`${dist}/cjs`, cssPath, 'style/style.css'), code.css)
await dest(
join(`${dist}/cjs`, cssPath, 'style/css.js'),
`import './style.css'`,
)

// copy harmonycss
if (file.indexOf('countup') === -1) {
await copy(join(__dirname, '../', file.replace('scss', 'harmony.css')), join(`${dist}/cjs`, cssPath, 'style/style.harmony.css'))
await copy(join(__dirname, '../', file.replace('scss', 'harmony.css')), join(`${dist}/es`, cssPath, 'style/style.harmony.css'))
}

// 删除 import
// 写入 style.scss
const atRules = []
await postcss([
const postcssRes = await postcss([
{
postcssPlugin: 'remove-atrule',
AtRule(root) {
Expand All @@ -391,13 +384,22 @@ async function buildCSS(p) {
},
},
])
.process(button, { from: loadPath, syntax: scss })
.process(scssContent, { from: loadPath, syntax: scss })
.then((result) => {
dest(join(`${dist}/es`, cssPath, `style/${base}`), result.css)
dest(join(`${dist}/cjs`, cssPath, `style/${base}`), result.css)
return result
})
const themeDir = themeName ? `style-${themeName}` : 'style'
await dest(join(`${dist}/es`, cssPath, `${themeDir}/${base}`), postcssRes.css)
await dest(join(`${dist}/cjs`, cssPath, `${themeDir}/${base}`), postcssRes.css)

const code = sass.compileString(variables + '\n' + postcssRes.css.replaceAll('../../../../', '../../'), {
loadPaths: [loadPath],
})
await dest(join(`${dist}/es`, cssPath, `${themeDir}/style.css`), code.css)
await dest(join(`${dist}/cjs`, cssPath, `${themeDir}/style.css`), code.css)

const jsContent = []
const cssContent = []
atRules.forEach((rule) => {
rule = rule.replaceAll('\'', '')
if (rule.indexOf('../styles/') > -1) {
Expand All @@ -407,18 +409,33 @@ async function buildCSS(p) {
const base = basename(rule)
const ext = extname(base)
const name = base.replace(ext, '')
jsContent.push(`import '../../${name}/style';`)
jsContent.push(`import '../../${name}/${themeDir}';`)
cssContent.push(`import '../../${name}/${themeDir}/css';`)
}
})
jsContent.push(`import './${base}';`)
cssContent.push(`import './style.css';`)

await dest(
join(`${dist}/cjs`, cssPath, `style/index.js`),
join(`${dist}/cjs`, cssPath, `${themeDir}/index.js`),
jsContent.join('\n'),
)
await dest(join(`${dist}/es`, cssPath, `style/index.js`), jsContent.join('\n'))
}
await dest(join(`${dist}/es`, cssPath, `${themeDir}/index.js`), jsContent.join('\n'))

// 写 css 文件
await dest(join(`${dist}/es`, cssPath, `${themeDir}/css.js`), cssContent.join('\n'))
await dest(
join(`${dist}/cjs`, cssPath, `${themeDir}/css.js`),
cssContent.join('\n'),
)

// copy harmonycss
if (file.indexOf('countup') === -1) {
const harmonyCss = join(__dirname, '../', file.replace('scss', 'harmony.css'))
await copy(harmonyCss, join(`${dist}/cjs`, cssPath, 'style/style.harmony.css'))
await copy(harmonyCss, join(`${dist}/es`, cssPath, 'style/style.harmony.css'))
}
}
}

function generateReleasePackageJson() {
Expand Down Expand Up @@ -474,18 +491,36 @@ console.time('build UMD')
await buildUMD()
console.timeEnd('build UMD')

console.time('Build CSS')
await buildCSS()
console.timeEnd('Build CSS')

console.time('Copy Styles')
await copyStyles()
console.timeEnd('Copy Styles')

console.time('Build CSS')
await buildCSS()
console.timeEnd('Build CSS')

console.time('Build jmapp CSS')
await buildCSS('jmapp')
console.timeEnd('Build CSS')

console.time('Build jrkf CSS')
await buildCSS('jrkf')
console.timeEnd('Build jrkf CSS')

console.time('Build All CSS')
await buildAllCSS()
console.timeEnd('Build All CSS')

console.time('Build All jrkf CSS')
await buildAllCSS('jrkf')
console.timeEnd('Build All jrkf CSS')

console.time('Build All jmapp CSS')
await buildAllCSS('jmapp')
console.timeEnd('Build All jmapp CSS')


console.time('Build Theme CSS')
await buildThemeCSS()
console.timeEnd('Build Theme CSS')
Expand Down
Loading
Loading