提交 88439291 编写于 作者: fxy060608's avatar fxy060608

wip(mp): nvue css

上级 72ad6aef
...@@ -8,15 +8,25 @@ import { ...@@ -8,15 +8,25 @@ import {
injectCssPostPlugin, injectCssPostPlugin,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
let appCss = ''
export const configResolved: Plugin['configResolved'] = (config) => { export const configResolved: Plugin['configResolved'] = (config) => {
removePlugins('vite:import-analysis', config) removePlugins('vite:import-analysis', config)
injectCssPlugin(config) injectCssPlugin(config)
injectCssPostPlugin(config, { injectCssPostPlugin(config, {
extname: '.css', extname: '.css',
appCss: fs.readFileSync( chunkCss(filename, cssCode) {
require.resolve('@dcloudio/uni-app-plus/dist/style.css'), if (filename === 'app.css') {
'utf8' if (!appCss) {
), appCss = fs.readFileSync(
require.resolve('@dcloudio/uni-app-plus/dist/style.css'),
'utf8'
)
}
return appCss + '\n' + cssCode
}
return cssCode
},
}) })
injectAssetPlugin(config) injectAssetPlugin(config)
} }
...@@ -10,7 +10,6 @@ import { ...@@ -10,7 +10,6 @@ import {
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
export function uniManifestJsonPlugin(): Plugin { export function uniManifestJsonPlugin(): Plugin {
let manifestJson: Record<string, any>
return defineUniManifestJsonPlugin((opts) => { return defineUniManifestJsonPlugin((opts) => {
return { return {
name: 'vite:uni-app-manifest-json', name: 'vite:uni-app-manifest-json',
...@@ -27,19 +26,13 @@ export function uniManifestJsonPlugin(): Plugin { ...@@ -27,19 +26,13 @@ export function uniManifestJsonPlugin(): Plugin {
).forEach((filepath) => { ).forEach((filepath) => {
this.addWatchFile(filepath) this.addWatchFile(filepath)
}) })
manifestJson = normalizeAppManifestJson( const manifestJson = normalizeAppManifestJson(
parseJson(code), parseJson(code),
parsePagesJsonOnce( parsePagesJsonOnce(
process.env.UNI_INPUT_DIR, process.env.UNI_INPUT_DIR,
process.env.UNI_PLATFORM process.env.UNI_PLATFORM
) )
) )
return {
code: '',
map: this.getCombinedSourcemap(),
}
},
generateBundle() {
// 生成一个空的app-config.js,兼容基座已有规范 // 生成一个空的app-config.js,兼容基座已有规范
this.emitFile({ this.emitFile({
fileName: `app-config.js`, fileName: `app-config.js`,
...@@ -51,6 +44,10 @@ export function uniManifestJsonPlugin(): Plugin { ...@@ -51,6 +44,10 @@ export function uniManifestJsonPlugin(): Plugin {
type: 'asset', type: 'asset',
source: JSON.stringify(manifestJson, null, 2), source: JSON.stringify(manifestJson, null, 2),
}) })
return {
code: '',
map: this.getCombinedSourcemap(),
}
}, },
} }
}) })
......
...@@ -11,7 +11,6 @@ import { ...@@ -11,7 +11,6 @@ import {
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
export function uniPagesJsonPlugin(): Plugin { export function uniPagesJsonPlugin(): Plugin {
let pagesJson: UniApp.PagesJson
return defineUniPagesJsonPlugin((opts) => { return defineUniPagesJsonPlugin((opts) => {
return { return {
name: 'vite:uni-app-pages-json', name: 'vite:uni-app-pages-json',
...@@ -26,20 +25,13 @@ export function uniPagesJsonPlugin(): Plugin { ...@@ -26,20 +25,13 @@ export function uniPagesJsonPlugin(): Plugin {
).forEach((filepath) => { ).forEach((filepath) => {
this.addWatchFile(filepath) this.addWatchFile(filepath)
}) })
pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM) const pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM)
// TODO subpackages // TODO subpackages
pagesJson.pages.forEach((page) => { pagesJson.pages.forEach((page) => {
this.addWatchFile( this.addWatchFile(
path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue') path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue')
) )
}) })
return {
code:
`import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson),
map: this.getCombinedSourcemap(),
}
},
generateBundle() {
this.emitFile({ this.emitFile({
fileName: `app-config-service.js`, fileName: `app-config-service.js`,
type: 'asset', type: 'asset',
...@@ -48,6 +40,11 @@ export function uniPagesJsonPlugin(): Plugin { ...@@ -48,6 +40,11 @@ export function uniPagesJsonPlugin(): Plugin {
parseManifestJsonOnce(process.env.UNI_INPUT_DIR) parseManifestJsonOnce(process.env.UNI_INPUT_DIR)
), ),
}) })
return {
code:
`import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson),
map: this.getCombinedSourcemap(),
}
}, },
} }
}) })
......
...@@ -13,6 +13,7 @@ const postcssLoader = { ...@@ -13,6 +13,7 @@ const postcssLoader = {
options: { options: {
sourceMap: false, sourceMap: false,
postcssOptions: { postcssOptions: {
config: false,
parser: require('postcss-comment'), parser: require('postcss-comment'),
plugins: [ plugins: [
require('postcss-import')({ require('postcss-import')({
......
view,
label,
swiper-item,
scroll-view {
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: flex-start;
}
view,
image,
input,
scroll-view,
swiper,
swiper-item,
text,
textarea,
video {
position: relative;
border: 0px solid #000000;
box-sizing: border-box;
}
swiper-item {
position: absolute;
}
button {
margin: 0;
}
import fs from 'fs'
import path from 'path' import path from 'path'
import { hasOwn } from '@vue/shared' import { hasOwn } from '@vue/shared'
import { parseJson } from '../json' import { parseJson } from '../json'
...@@ -41,6 +42,7 @@ function parsePagesJson( ...@@ -41,6 +42,7 @@ function parsePagesJson(
pages: [], pages: [],
} }
const pageJsons: Record<string, PageWindowOptions> = {} const pageJsons: Record<string, PageWindowOptions> = {}
const nvuePages: string[] = []
// preprocess // preprocess
const pagesJson = parseJson(jsonStr, true) as UniApp.PagesJson const pagesJson = parseJson(jsonStr, true) as UniApp.PagesJson
if (!pagesJson) { if (!pagesJson) {
...@@ -48,6 +50,11 @@ function parsePagesJson( ...@@ -48,6 +50,11 @@ function parsePagesJson(
} }
function addPageJson(pagePath: string, style: UniApp.PagesJsonPageStyle) { function addPageJson(pagePath: string, style: UniApp.PagesJsonPageStyle) {
if (
fs.existsSync(path.join(process.env.UNI_INPUT_DIR, pagePath + '.nvue'))
) {
nvuePages.push(pagePath)
}
pageJsons[pagePath] = parseWindowOptions(style, platform, windowOptionsMap) pageJsons[pagePath] = parseWindowOptions(style, platform, windowOptionsMap)
} }
// pages // pages
...@@ -116,5 +123,6 @@ function parsePagesJson( ...@@ -116,5 +123,6 @@ function parsePagesJson(
return { return {
appJson, appJson,
pageJsons, pageJsons,
nvuePages,
} }
} }
export * from './nvue'
export * from './event' export * from './event'
export { transformVueComponentImports } from './transformImports' export { transformVueComponentImports } from './transformImports'
import fs from 'fs'
import path from 'path'
import { getNVueFlexDirection } from '../json/app/manifest/nvue'
export function genNVueCssCode(manifestJson: Record<string, any>) {
let nvueCssCode = fs.readFileSync(
path.resolve(__dirname, '../../lib/nvue.css'),
'utf8'
)
const flexDirection = getNVueFlexDirection(manifestJson)
if (flexDirection !== 'column') {
nvueCssCode = nvueCssCode.replace('column', flexDirection)
}
return nvueCssCode
}
...@@ -228,7 +228,13 @@ function findCssModuleIds( ...@@ -228,7 +228,13 @@ function findCssModuleIds(
*/ */
export function cssPostPlugin( export function cssPostPlugin(
config: ResolvedConfig, config: ResolvedConfig,
{ appCss, extname }: { appCss?: string; extname: string } {
chunkCss,
extname,
}: {
chunkCss: (filename: string, cssCode: string) => string
extname: string
}
): Plugin { ): Plugin {
// styles initialization in buildStart causes a styling loss in watch // styles initialization in buildStart causes a styling loss in watch
const styles: Map<string, string> = new Map<string, string>() const styles: Map<string, string> = new Map<string, string>()
...@@ -303,9 +309,9 @@ export function cssPostPlugin( ...@@ -303,9 +309,9 @@ export function cssPostPlugin(
.join('\n') .join('\n')
} }
for (const filename of cssChunks.keys()) { for (const filename of cssChunks.keys()) {
const cssCode = genCssCode(filename)
let source = await processChunkCSS( let source = await processChunkCSS(
(filename === 'app.css' ? (appCss || '') + '\n' : '') + chunkCss ? chunkCss(filename, cssCode) : cssCode,
genCssCode(filename),
{ dirname: path.dirname(filename), inlined: false, minify: true } { dirname: path.dirname(filename), inlined: false, minify: true }
) )
this.emitFile({ this.emitFile({
......
...@@ -19,9 +19,15 @@ export function injectCssPlugin(config: ResolvedConfig) { ...@@ -19,9 +19,15 @@ export function injectCssPlugin(config: ResolvedConfig) {
export function injectCssPostPlugin( export function injectCssPostPlugin(
config: ResolvedConfig, config: ResolvedConfig,
{ appCss, extname }: { appCss?: string; extname: string } {
chunkCss,
extname,
}: {
chunkCss: (filename: string, cssCode: string) => string
extname: string
}
) { ) {
replacePlugins([cssPostPlugin(config, { appCss, extname })], config) replacePlugins([cssPostPlugin(config, { chunkCss, extname })], config)
} }
export function replacePlugins(plugins: Plugin[], config: ResolvedConfig) { export function replacePlugins(plugins: Plugin[], config: ResolvedConfig) {
......
import debug from 'debug'
import { Plugin } from 'vite' import { Plugin } from 'vite'
import { import {
removePlugins, removePlugins,
injectAssetPlugin, injectAssetPlugin,
injectCssPlugin, injectCssPlugin,
injectCssPostPlugin, injectCssPostPlugin,
normalizePath,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { UniMiniProgramPluginOptions } from '.' import { UniMiniProgramPluginOptions } from '.'
import { getNVueCssPaths } from '../plugins/pagesJson'
const debugNVueCss = debug('vite:uni:nvue-css')
const shadowCss = `page::after{position:fixed;content:'';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}`
export function createConfigResolved({ export function createConfigResolved({
style: { extname }, style: { extname },
...@@ -16,7 +22,21 @@ export function createConfigResolved({ ...@@ -16,7 +22,21 @@ export function createConfigResolved({
injectCssPlugin(config) injectCssPlugin(config)
injectCssPostPlugin(config, { injectCssPostPlugin(config, {
extname, extname,
appCss: '', chunkCss(filename, cssCode) {
if (config.isProduction && filename === 'app' + extname) {
return cssCode + shadowCss
}
const nvueCssPaths = getNVueCssPaths(config)
if (!nvueCssPaths || !nvueCssPaths.length) {
return cssCode
}
const normalized = normalizePath(filename)
if (nvueCssPaths.find((pageCssPath) => pageCssPath === normalized)) {
debugNVueCss(normalized)
return `@import "/nvue.wxss";\n` + cssCode
}
return cssCode
},
}) })
injectAssetPlugin(config) injectAssetPlugin(config)
} }
......
...@@ -8,6 +8,8 @@ import { ...@@ -8,6 +8,8 @@ import {
normalizeNodeModules, normalizeNodeModules,
resolveBuiltIn, resolveBuiltIn,
UniVitePlugin, UniVitePlugin,
genNVueCssCode,
parseManifestJsonOnce,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { uniOptions } from './uni' import { uniOptions } from './uni'
...@@ -59,6 +61,7 @@ export function uniMiniProgramPlugin( ...@@ -59,6 +61,7 @@ export function uniMiniProgramPlugin(
const { const {
vite: { alias, copyOptions }, vite: { alias, copyOptions },
template, template,
style,
} = options } = options
const emitFile: (emittedFile: EmittedFile) => string = (emittedFile) => { const emitFile: (emittedFile: EmittedFile) => string = (emittedFile) => {
if (emittedFile.type === 'asset') { if (emittedFile.type === 'asset') {
...@@ -70,11 +73,12 @@ export function uniMiniProgramPlugin( ...@@ -70,11 +73,12 @@ export function uniMiniProgramPlugin(
) )
).replace(EXTNAME_VUE_RE, template.extname) ).replace(EXTNAME_VUE_RE, template.extname)
debugMp(outputFilename) debugMp(outputFilename)
fs.outputFileSync(outputFilename, emittedFile.source!) fs.outputFile(outputFilename, emittedFile.source!)
return outputFilename return outputFilename
} }
return '' return ''
} }
let isFirst = true
return { return {
name: 'vite:uni-mp', name: 'vite:uni-mp',
uni: uniOptions({ uni: uniOptions({
...@@ -93,5 +97,18 @@ export function uniMiniProgramPlugin( ...@@ -93,5 +97,18 @@ export function uniMiniProgramPlugin(
} }
}, },
configResolved: createConfigResolved(options), configResolved: createConfigResolved(options),
generateBundle() {
if (isFirst) {
// 仅生成一次
isFirst = false
this.emitFile({
type: 'asset',
fileName: 'nvue' + style.extname,
source: genNVueCssCode(
parseManifestJsonOnce(process.env.UNI_INPUT_DIR)
),
})
}
},
} }
} }
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import debug from 'debug' import debug from 'debug'
import { Plugin } from 'vite' import { Plugin, ResolvedConfig } from 'vite'
import { import {
AppJson, AppJson,
defineUniPagesJsonPlugin, defineUniPagesJsonPlugin,
...@@ -19,13 +18,22 @@ import { UniMiniProgramPluginOptions } from '../plugin' ...@@ -19,13 +18,22 @@ import { UniMiniProgramPluginOptions } from '../plugin'
const debugPagesJson = debug('vite:uni:pages-json') const debugPagesJson = debug('vite:uni:pages-json')
const nvueCssPathsCache = new Map<ResolvedConfig, string[]>()
export function getNVueCssPaths(config: ResolvedConfig) {
return nvueCssPathsCache.get(config)
}
export function uniPagesJsonPlugin( export function uniPagesJsonPlugin(
options: UniMiniProgramPluginOptions options: UniMiniProgramPluginOptions
): Plugin { ): Plugin {
let resolvedConfig: ResolvedConfig
return defineUniPagesJsonPlugin((opts) => { return defineUniPagesJsonPlugin((opts) => {
return { return {
name: 'vite:uni-mp-pages-json', name: 'vite:uni-mp-pages-json',
enforce: 'pre', enforce: 'pre',
configResolved(config) {
resolvedConfig = config
},
transform(code, id) { transform(code, id) {
if (!opts.filter(id)) { if (!opts.filter(id)) {
return return
...@@ -36,7 +44,7 @@ export function uniPagesJsonPlugin( ...@@ -36,7 +44,7 @@ export function uniPagesJsonPlugin(
this.addWatchFile(filepath) this.addWatchFile(filepath)
}) })
const manifestJson = parseManifestJsonOnce(inputDir) const manifestJson = parseManifestJsonOnce(inputDir)
const { appJson, pageJsons } = parseMiniProgramPagesJson( const { appJson, pageJsons, nvuePages } = parseMiniProgramPagesJson(
code, code,
process.env.UNI_PLATFORM, process.env.UNI_PLATFORM,
{ {
...@@ -48,6 +56,11 @@ export function uniPagesJsonPlugin( ...@@ -48,6 +56,11 @@ export function uniPagesJsonPlugin(
subpackages: options.app.subpackages, subpackages: options.app.subpackages,
} }
) )
nvueCssPathsCache.set(
resolvedConfig,
nvuePages.map((pagePath) => pagePath + options.style.extname)
)
addMiniProgramAppJson(appJson) addMiniProgramAppJson(appJson)
Object.keys(pageJsons).forEach((name) => { Object.keys(pageJsons).forEach((name) => {
addMiniProgramPageJson(name, pageJsons[name]) addMiniProgramPageJson(name, pageJsons[name])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册