Skip to content

Commit

Permalink
feat: add build style (#1201)
Browse files Browse the repository at this point in the history
* fix: eliminate TS6053 error

* chore: add deps

* feat: add build style

* refactor(antd): use build style

* refactor(next): use build style

* fix: eliminate ts error in rollup-plugin-postcss

* feat: add build all styles output option
  • Loading branch information
atzcl authored Apr 9, 2021
1 parent 1da31ca commit 3ceedb1
Show file tree
Hide file tree
Showing 17 changed files with 349 additions and 80 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
"devDependencies": {
"@alifd/next": "^1.19.1",
"@rollup/plugin-commonjs": "^17.0.0",
"less": "^4.1.1",
"less-plugin-npm-import": "^2.1.0",
"rollup-plugin-postcss": "^4.0.0",
"postcss": "^8.0.0",
"@testing-library/jest-dom": "^5.0.0",
"@testing-library/react": "^11.2.3",
"@testing-library/vue": "^5.6.1",
Expand Down Expand Up @@ -183,4 +187,4 @@
"dependencies": {
"@ant-design/icons": "^4.0.2"
}
}
}
13 changes: 13 additions & 0 deletions packages/antd/build-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { build } from '../../scripts/build-style'

build({
esStr: 'antd/es/',
libStr: 'antd/lib/',
styleEntry: 'style.less',
allStylesOutputFile: 'dist/antd.css',
// antd/es/button/style/index ===> antd/es/button/style/css
importCssCompilerToCssTransform: (v) =>
v.replace(/'antd\/(es|lib)\/(.*)'/, (subStr) =>
subStr.replace(/\/style\/index'$/, `/style/css'`)
),
})
45 changes: 0 additions & 45 deletions packages/antd/copy.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/antd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
},
"scripts": {
"start": "dumi dev",
"build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd && npm run copy:style",
"copy:style": "cross-env INIT_RUN=true ts-node copy",
"build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:style",
"build:style": "ts-node build-style",
"build:cjs": "tsc --declaration",
"build:esm": "tsc --declaration --module es2015 --outDir esm",
"build:umd": "rollup --config",
Expand Down
2 changes: 1 addition & 1 deletion packages/antd/src/form-layout/style.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import './style.less'
import './style.less'
2 changes: 1 addition & 1 deletion packages/antd/src/form/style.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import './style.less'
import './style.less'
13 changes: 13 additions & 0 deletions packages/next/build-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { build } from '../../scripts/build-style'

build({
esStr: '@alifd/next/es/',
libStr: '@alifd/next/lib/',
styleEntry: 'main.scss',
allStylesOutputFile: 'dist/next.css',
// antd/es/button/style/index ===> antd/es/button/style/css
importCssCompilerToCssTransform: (v) =>
v.replace(/'@alifd\/next\/(es|lib)\/(.*)'/g, (subStr) =>
subStr.replace(/\/style'$/, `/index.css'`)
),
})
6 changes: 0 additions & 6 deletions packages/next/copy.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
},
"scripts": {
"start": "dumi dev",
"build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd && npm run copy:style",
"copy:style": "cross-env INIT_RUN=true ts-node copy",
"build": "rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:style",
"build:style": "ts-node build-style",
"build:cjs": "tsc --declaration",
"build:esm": "tsc --declaration --module es2015 --outDir esm",
"build:umd": "rollup --config",
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/form-layout/style.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import './main.scss'
import './main.scss'
2 changes: 1 addition & 1 deletion packages/next/src/form/style.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import './main.scss'
import './main.scss'
61 changes: 61 additions & 0 deletions scripts/build-style/buildAllStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import fs from 'fs-extra'
import { join } from 'path'
import { identifier } from 'safe-identifier'

import typescript from 'rollup-plugin-typescript2'

import { build, getRollupBasePlugin } from './helper'

/**
* @ref https://github.com/egoist/rollup-plugin-postcss/blob/master/src/postcss-loader.js
*/
const styleInjectPath = require
.resolve('style-inject/dist/style-inject.es')
.replace(/[\\/]+/g, '/')

let styleInjectText = ''
const generateCssStyleInject = async (cssFilePath: string) => {
if (!styleInjectText) {
styleInjectText = (await fs.readFile(styleInjectPath)).toString()
styleInjectText = styleInjectText.replace('export default styleInject;', '')
}

let cssContent = (await fs.readFile(cssFilePath)).toString()

// 删除可能存在的 sourceMap 注释
cssContent = cssContent.replace(/\n\/\*#(.*)css.map\s\*\//g, '')

const cssVariableName = identifier('css', true)

return fs.outputFile(
cssFilePath.replace('.css', '.js'),
styleInjectText +
`\nvar ${cssVariableName} = "${cssContent}";\n\nstyleInject(${cssVariableName})`
)
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const buildAllStyles = async (outputFile: string) => {
const outputFilePath = 'dist/formily.css'

await build({
input: 'src/style.ts',
output: {
file: outputFile,
},
plugins: [
typescript({
tsconfig: './tsconfig.json',
tsconfigOverride: {
compilerOptions: {
module: 'ESNext',
declaration: false,
},
},
}),
...getRollupBasePlugin(),
],
})

return generateCssStyleInject(join(process.cwd(), outputFile))
}
116 changes: 116 additions & 0 deletions scripts/build-style/buildStyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { copy, readFile, outputFile, existsSync } from 'fs-extra'

import { getRollupBasePlugin, build } from './helper'

export type BuildStyleOptions = {
filename: string
styleEntry: string
importCssCompilerToCssTransform?: (fileContent: string) => string
}

const importCssCompilerToCss = async ({
fileName,
outputFileName,
styleEntry,
transform,
}: {
outputFileName: string
fileName: string
styleEntry: string
transform?: BuildStyleOptions['importCssCompilerToCssTransform']
}) => {
let styleFileContent = (await readFile(fileName)).toString()

if (!styleFileContent) {
return
}

styleFileContent = styleFileContent.replace(
new RegExp(`\.\/${styleEntry}`),
'./css.css'
)

return outputFile(
outputFileName,
transform?.(styleFileContent) || styleFileContent
)
}

const getPaths = (filename: string, moduleType: 'esm' | 'lib') => {
const styleFilePath = filename
.replace(/src\//, `${moduleType}/`)
.replace(/\.ts$/, '.js')
const cssFilePath = styleFilePath.replace(/\/\w+\.js$/, '/css.css')
const cssSourceMapFilePath = `${cssFilePath}.map`

return {
// esm/array-base/style.js
styleFilePath,
// esm/array-base/css.css
cssFilePath,
// esm/array-base/css.css.map
cssSourceMapFilePath,
}
}

const buildCss = async ({
filename,
esmPaths,
libPaths,
styleEntry,
}: Pick<BuildStyleOptions, 'filename' | 'styleEntry'> &
Record<'esmPaths' | 'libPaths', ReturnType<typeof getPaths>>) => {
// src/array-base/style.ts ===> src/array-base/style.less
const input = filename.replace(/style\.ts$/, styleEntry)

if (!existsSync(input)) {
return
}

await build({
input,
output: {
file: esmPaths.cssFilePath,
},
plugins: getRollupBasePlugin(),
})

return Promise.all([
copy(esmPaths.cssFilePath, libPaths.cssFilePath),
existsSync(esmPaths.cssSourceMapFilePath) &&
copy(esmPaths.cssSourceMapFilePath, libPaths.cssSourceMapFilePath),
])
}

export const buildStyle = async ({
// xxxx/style.ts
filename,
// example: style.less/main.scss
styleEntry,
importCssCompilerToCssTransform,
}: BuildStyleOptions): Promise<unknown> => {
const esmPaths = getPaths(filename, 'esm')
const libPaths = getPaths(filename, 'lib')

await buildCss({
filename,
esmPaths,
libPaths,
styleEntry,
})

return Promise.all([
importCssCompilerToCss({
fileName: esmPaths.styleFilePath,
outputFileName: esmPaths.cssFilePath.replace(/\.css$/, '.js'),
styleEntry,
transform: importCssCompilerToCssTransform,
}),
importCssCompilerToCss({
fileName: libPaths.styleFilePath,
outputFileName: libPaths.cssFilePath.replace(/\.css$/, '.js'),
styleEntry,
transform: importCssCompilerToCssTransform,
}),
])
}
59 changes: 59 additions & 0 deletions scripts/build-style/copy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { copy, readFile, writeFile, existsSync } from 'fs-extra'
import glob from 'glob'

export type CopyBaseOptions = Record<'esStr' | 'libStr', string>

const importLibToEs = async ({
libStr,
esStr,
filename,
}: CopyBaseOptions & { filename: string }) => {
if (!existsSync(filename)) {
return Promise.resolve()
}

const fileContent: string = (await readFile(filename)).toString()

return writeFile(
filename,
fileContent.replace(new RegExp(libStr, 'g'), esStr)
)
}

export const runCopy = ({
resolveForItem,
...lastOpts
}: CopyBaseOptions & { resolveForItem?: (filename: string) => unknown }) => {
return new Promise((resolve, reject) => {
glob(`./src/**/*`, (err, files) => {
if (err) {
return reject(err)
}

const all = [] as Promise<unknown>[]

for (let i = 0; i < files.length; i += 1) {
const filename = files[i]

resolveForItem?.(filename)

if (/\.(less|scss)$/.test(filename)) {
all.push(copy(filename, filename.replace(/src\//, 'esm/')))
all.push(copy(filename, filename.replace(/src\//, 'lib/')))

continue
}

if (/\/style.ts$/.test(filename)) {
importLibToEs({
...lastOpts,
filename: filename.replace(/src\//, 'esm/').replace(/\.ts$/, '.js'),
})

continue
}
}
})
})
}
Loading

0 comments on commit 3ceedb1

Please sign in to comment.