Skip to content

Commit

Permalink
feat(taro-cli): 优化小程序staticDirectory输出和解析
Browse files Browse the repository at this point in the history
  • Loading branch information
jiangzm committed Dec 19, 2019
1 parent 5b8bf19 commit bde5a2f
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 73 deletions.
12 changes: 12 additions & 0 deletions docs/config-detail.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,18 @@ copy: {

专属于小程序的配置。

### weapp.publicPath

`publicPath`设置输出解析文件的目录。

### weapp.staticDirectory

`staticDirectory`小程序编译后的静态文件(仅图片,字体,音/视频)放置目录(相对于`outputRoot`的)。

### weapp.useHashName

`useHashName`输出静态文件是否使用hash名称,配置了`staticDirectory`才生效,默认`[name].[hash].[ext]`, 可配置`false`将输出原文件名。

### weapp.compile

小程序编译过程的相关配置。
Expand Down
25 changes: 16 additions & 9 deletions packages/taro-cli/src/mini/astProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import generate from 'babel-generator'
import traverse, { NodePath } from 'babel-traverse'
import * as _ from 'lodash'
import { Config as IConfig } from '@tarojs/taro'
import getHashName from '../util/hash'
import { getHashName } from '../util/hash'
import { normalizeUrl } from '../util'

const template = require('babel-template')

Expand Down Expand Up @@ -115,7 +116,7 @@ function analyzeImportUrl ({
projectConfig,
buildAdapter
} = getBuildData()
const publicPath = (projectConfig.weapp || ({} as any)).publicPath
const { publicPath, staticDirectory, useHashName } = Object.assign({}, projectConfig.weapp)
if (value.indexOf('.') === 0) {
let importPath = path.resolve(path.dirname(sourceFilePath), value)
importPath = resolveScriptPath(importPath)
Expand Down Expand Up @@ -177,9 +178,12 @@ function analyzeImportUrl ({
showPath = vpath.replace(nodeModulesPath, `/${npmConfig.name}`)
} else {
showPath = vpath.replace(sourceDir, '')
if (publicPath) {
const hashName = getHashName(vpath)
showPath = (/\/$/.test(publicPath) ? publicPath : publicPath + '/') + hashName
if (publicPath || staticDirectory) {
if (staticDirectory && useHashName !== false) {
const hashName = getHashName(vpath, useHashName)
showPath = showPath.replace(path.basename(showPath), hashName)
}
showPath = normalizeUrl(publicPath||'', staticDirectory||'', showPath)
}
}
if (defaultSpecifier) {
Expand Down Expand Up @@ -271,7 +275,7 @@ export function parseAst (
projectConfig,
quickappManifest
} = getBuildData()
const publicPath = (projectConfig.weapp || {} as any).publicPath
const { publicPath, staticDirectory, useHashName} = Object.assign({}, projectConfig.weapp)
const notExistNpmList = getNotExistNpmList()
const taroMiniAppFramework = `@tarojs/taro-${buildAdapter}`
let configObj: IConfig = {}
Expand Down Expand Up @@ -876,9 +880,12 @@ export function parseAst (
showPath = vpath.replace(nodeModulesPath, `/${npmConfig.name}`)
} else {
showPath = vpath.replace(sourceDir, '')
if (publicPath) {
const hashName = getHashName(vpath)
showPath = (/\/$/.test(publicPath) ? publicPath : publicPath + '/') + hashName
if (publicPath || staticDirectory) {
if (staticDirectory && useHashName !== false) {
const hashName = getHashName(vpath, useHashName)
showPath = showPath.replace(path.basename(showPath), hashName)
}
showPath = normalizeUrl(publicPath||'', staticDirectory||'', showPath)
}
}
astPath.replaceWith(t.stringLiteral(showPath.replace(/\\/g, '/')))
Expand Down
81 changes: 47 additions & 34 deletions packages/taro-cli/src/mini/compileStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as autoprefixer from 'autoprefixer'
import * as postcss from 'postcss'
import * as pxtransform from 'postcss-pxtransform'
import rewriter from '../quickapp/style-rewriter'
import getHashName from '../util/hash'
import browserList from '../config/browser_list'
import {
resolveNpmPkgMainPath,
Expand All @@ -18,12 +17,15 @@ import {
isNpmPkg,
processStyleImports,
promoteRelativePath,
getBabelConfig
getBabelConfig,
normalizeUrl
} from '../util'
import { CSS_EXT, FILE_PROCESSOR_MAP, DEVICE_RATIO_NAME, BUILD_TYPES } from '../util/constants'
import { IMiniAppConfig } from '../util/types'
import { getHashName } from '../util/hash'

import {
copyFilesFromSrcToOutput,
getBuildData
} from './helper'

Expand Down Expand Up @@ -107,9 +109,10 @@ export async function processStyleUseCssModule (styleObj: IStyleObj): Promise<an
}

async function processStyleWithPostCSS (styleObj: IStyleObj): Promise<string> {
const { appPath, outputDir,projectConfig, npmConfig, isProduction, buildAdapter } = getBuildData()
const { appPath, outputDir, sourceDir, projectConfig, npmConfig, isProduction, buildAdapter } = getBuildData()
const styleFilePath = styleObj.filePath.replace(sourceDir, outputDir)
const weappConf = Object.assign({}, projectConfig.weapp)
const publicPath = weappConf.publicPath
const { publicPath, staticDirectory, useHashName } = weappConf
const useModuleConf = weappConf.module || {}
const customPostcssConf = useModuleConf.postcss || {}
const customCssModulesConf = Object.assign({
Expand Down Expand Up @@ -144,7 +147,6 @@ async function processStyleWithPostCSS (styleObj: IStyleObj): Promise<string> {
postcssPxtransformOption[DEVICE_RATIO_NAME] = projectConfig.deviceRatio
}

const maxSize = (customUrlConf.config.limit || 1024) / 1024
const postcssPxtransformConf = Object.assign({}, postcssPxtransformOption, customPxtransformConf, customPxtransformConf.config)
const processors: any[] = []
if (customAutoprefixerConf.enable) {
Expand All @@ -154,50 +156,61 @@ async function processStyleWithPostCSS (styleObj: IStyleObj): Promise<string> {
processors.push(pxtransform(postcssPxtransformConf))
}
if (customUrlConf.enable) {
let inlineOpts = {}
const url = customUrlConf.config.url || 'inline'
if (url === 'inline' && !publicPath) {
inlineOpts = {
encodeType: 'base64',
maxSize,
url
let options: any[] = []
const config = customUrlConf.config
if (Array.isArray(config)) {
// 数组模式参数同: https://github.com/postcss/postcss-url#muiltiple-options
options = options.concat(config)
} else {
const url = config.url || 'inline'
const limit = config.limit || 1024
if (url !== 'inline') {
options.push(config)
} else if (limit >= 0) {
// limit < 0 时忽略`inline`
options.push({
url,
encodeType: 'base64',
maxSize: limit / 1024,
...config
})
}
}

const customOption = {
multi: true,
url: (assets, dir, opts) => {
if (!/^(https?|data):/.test(assets.url)) {
const relativePath = path.relative(sourceDir, assets.absolutePath)
const outputFile = path.resolve(outputDir, `./${staticDirectory||''}`, `./${relativePath}`)

if (assets.absolutePath) {
copyFilesFromSrcToOutput([assets.absolutePath])

/***
* 修复小程序下css没有正确引用样式
* 当前位置只进行了文件hash转换并没有做文件copy操作
*/
if (publicPath && typeof url !== 'function') {
customUrlConf.config.url = (assets) => {
if (publicPath) {
assets.url = normalizeUrl(publicPath, staticDirectory||'', relativePath)
} else if (staticDirectory) {
assets.url = path.relative(path.dirname(styleFilePath), outputFile)
}

// 本地文件路径
if (/\./.test(assets.url)) {
const hashName = getHashName(assets.absolutePath);
assets.url = (/\/$/.test(publicPath) ? publicPath : publicPath + '/') + hashName;
if (useHashName !== false && staticDirectory) {
const hashName = getHashName(assets.absolutePath, useHashName)
assets.url = assets.url.replace(path.basename(assets.url), hashName)
}
}

// 目前只在头条小程序复现,避免影响,只针对头条处理
if(buildAdapter === BUILD_TYPES.TT){
const outputFile = path.resolve(outputDir,`./${assets.url}`);
fs.ensureDirSync(path.dirname(outputFile));
fs.copySync(assets.absolutePath,outputFile);
if (buildAdapter === BUILD_TYPES.TT) {
// 头条下不支持 / ,修正头条css background路径
assets.url = assets.url.replace(/^[\/]/,'');
assets.url = assets.url.replace(/^[\/]/,'')
}
}

return assets.url
}

}

const cssUrlParseConf = {
...inlineOpts,
...customUrlConf.config
}
processors.push(cssUrlParse(cssUrlParseConf))
options.push(customOption)
processors.push(cssUrlParse(options))
}

const defaultPostCSSPluginNames = ['autoprefixer', 'pxtransform', 'url', 'cssModules']
Expand Down
2 changes: 1 addition & 1 deletion packages/taro-cli/src/mini/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export async function buildSingleComponent (
}
// 编译依赖的脚本文件
if (isDifferentArray(fileDep['script'], res.scriptFiles)) {
await compileDepScripts(res.scriptFiles, !isQuickApp)
await Promise.all(compileDepScripts(res.scriptFiles, !isQuickApp))
}
const depComponents = getDepComponents()
// 编译样式文件
Expand Down
9 changes: 5 additions & 4 deletions packages/taro-cli/src/mini/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function buildWorkers (worker: string) {
const isDir = stats.isDirectory()
if (isFile) {
if (REG_SCRIPTS.test(filePath)) {
await compileDepScripts([filePath], true)
await Promise.all(compileDepScripts([filePath], true))
} else {
copyFilesFromSrcToOutput([filePath])
}
Expand Down Expand Up @@ -123,21 +123,22 @@ export async function buildEntry (): Promise<AppConfig> {
}
// 处理res.configObj 中的tabBar配置
const tabBar = res.configObj.tabBar
let tabBarIcons: string[] = []
if (tabBar && typeof tabBar === 'object' && !isEmptyObject(tabBar)) {
const {
list: listConfig,
iconPath: pathConfig,
selectedIconPath: selectedPathConfig
} = CONFIG_MAP[buildAdapter]
const list = tabBar[listConfig] || []
let tabBarIcons: string[] = []
list.forEach(item => {
item[pathConfig] && tabBarIcons.push(item[pathConfig])
item[selectedPathConfig] && tabBarIcons.push(item[selectedPathConfig])
})
tabBarIcons = tabBarIcons.map(item => path.resolve(sourceDir, item))
if (tabBarIcons && tabBarIcons.length) {
res.mediaFiles = res.mediaFiles.concat(tabBarIcons)
// res.mediaFiles = res.mediaFiles.concat(tabBarIcons)
copyFilesFromSrcToOutput(tabBarIcons, undefined, false)
}
}
if (buildAdapter === BUILD_TYPES.QUICKAPP) {
Expand Down Expand Up @@ -190,7 +191,7 @@ export async function buildEntry (): Promise<AppConfig> {
fileDep['style'] = res.styleFiles
fileDep['script'] = res.scriptFiles
fileDep['json'] = res.jsonFiles
fileDep['media'] = res.mediaFiles
fileDep['media'] = res.mediaFiles.concat(tabBarIcons)
dependencyTree.set(entryFilePath, fileDep)
return res.configObj
} catch (err) {
Expand Down
35 changes: 21 additions & 14 deletions packages/taro-cli/src/mini/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as path from 'path'
import * as _ from 'lodash'
import { Config } from '@tarojs/taro'
import * as wxTransformer from '@tarojs/transformer-wx'
import getHashName from '../util/hash'
import { getHashName } from '../util/hash'

import {
BUILD_TYPES,
Expand Down Expand Up @@ -308,18 +308,25 @@ export function initCopyFiles () {
isCopyingFiles.clear()
}

export function copyFilesFromSrcToOutput (files: string[], cb?: (sourceFilePath: string, outputFilePath: string) => void) {
export function copyFilesFromSrcToOutput (
files: string[],
cb?: (sourceFilePath: string, outputFilePath: string) => void,
outputStaticDir?: boolean
) {
const { nodeModulesPath, npmOutputDir, sourceDir, outputDir, appPath, projectConfig } = BuildData
const adapterConfig = Object.assign({}, projectConfig.weapp)
files.forEach(file => {
let outputFilePath
if (NODE_MODULES_REG.test(file)) {
outputFilePath = file.replace(nodeModulesPath, npmOutputDir)
} else {
if (adapterConfig.publicPath && adapterConfig.staticDirectory) {
const hashName = getHashName(file)
const staticPath = path.join(appPath, adapterConfig.staticDirectory, projectConfig.projectName || '')
outputFilePath = `${staticPath}/${hashName}`
if (adapterConfig.staticDirectory && outputStaticDir !== false) {
const staticPath = path.join(outputDir, adapterConfig.staticDirectory)
outputFilePath = file.replace(sourceDir, staticPath)
if (adapterConfig.useHashName !== false ) {
const hashName = getHashName(file, adapterConfig.useHashName)
outputFilePath = outputFilePath.replace(path.basename(outputFilePath), hashName)
}
} else {
outputFilePath = file.replace(sourceDir, outputDir)
}
Expand All @@ -336,14 +343,14 @@ export function copyFilesFromSrcToOutput (files: string[], cb?: (sourceFilePath:
if (!fs.existsSync(file)) {
printLog(processTypeEnum.ERROR, '文件', `${modifySrc} 不存在`)
} else {
fs.ensureDir(path.dirname(outputFilePath))
if (file === outputFilePath) {
return
}
if (cb) {
cb(file, outputFilePath)
} else {
fs.copySync(file, outputFilePath)
fs.ensureDirSync(path.dirname(outputFilePath))
// 文件位置不变或已存在则忽略
if (file !== outputFilePath) {
if (cb) {
cb(file, outputFilePath)
} else if(!fs.existsSync(outputFilePath)){
fs.copySync(file, outputFilePath)
}
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion packages/taro-cli/src/mini/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function transfromNativeComponents (configFile: string, componentConfig:
const buildDepComponentsRes = await buildDepComponents([{ path: componentJSPath, name: item, type: 'default' }])
return buildDepComponentsRes
}
await compileDepScripts([componentJSPath], true)
await Promise.all(compileDepScripts([componentJSPath], true))
} else {
return printLog(processTypeEnum.ERROR, '编译错误', `原生组件文件 ${componentJSPath} 不存在!`)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/taro-cli/src/mini/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export async function buildSinglePage (page: string) {
copyFileSync(pageJSONPath, outputPageJSONPath)
transfromNativeComponents(pageJSONPath, pageJSON)
}
await compileDepScripts([pageJs], true)
await Promise.all(compileDepScripts([pageJs], true))
copyFileSync(pageWXMLPath, outputPageWXMLPath)
if (fs.existsSync(pageWXSSPath)) {
await compileDepStyles(outputPageWXSSPath, [pageWXSSPath])
Expand Down Expand Up @@ -254,7 +254,7 @@ export async function buildSinglePage (page: string) {
}
// 编译依赖的脚本文件
if (isDifferentArray(fileDep['script'], res.scriptFiles)) {
await compileDepScripts(res.scriptFiles, !isQuickApp)
await Promise.all(compileDepScripts(res.scriptFiles, !isQuickApp))
}
// 编译样式文件
if (isDifferentArray(fileDep['style'], res.styleFiles) || isDifferentArray(depComponents.get(pageJs) || [], pageDepComponents)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/taro-cli/src/mini/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export function watchFiles () {
modifySource = modifySource.split(path.sep).join('/')
if (isImported) {
printLog(processTypeEnum.MODIFY, 'JS文件', modifySource)
await compileDepScripts([filePath], !isQuickApp)
await Promise.all(compileDepScripts([filePath], !isQuickApp))
} else {
printLog(processTypeEnum.WARNING, 'JS文件', `${modifySource} 没有被引用到,不会被编译`)
}
Expand Down
Loading

0 comments on commit bde5a2f

Please sign in to comment.