Skip to content

Commit

Permalink
feat(cli): support css module feature (#1007)
Browse files Browse the repository at this point in the history
* add css-module support

* small tweaks
  • Loading branch information
MrKou47 authored and luckyadam committed Nov 6, 2018
1 parent 119774f commit bc85775
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 5 deletions.
6 changes: 6 additions & 0 deletions packages/taro-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"css-to-react-native-transform": "^1.4.0",
"ejs": "^2.6.1",
"fs-extra": "^5.0.0",
"generic-names": "^2.0.1",
"glob": "^7.1.2",
"inquirer": "^5.2.0",
"klaw": "^2.1.1",
Expand All @@ -55,6 +56,11 @@
"minimatch": "^3.0.4",
"ora": "^2.0.0",
"postcss": "^6.0.22",
"postcss-modules-extract-imports": "^1.1.0",
"postcss-modules-local-by-default": "^1.2.0",
"postcss-modules-resolve-imports": "^1.3.0",
"postcss-modules-scope": "^1.1.0",
"postcss-modules-values": "^1.3.0",
"postcss-pxtransform": "1.2.0-alpha.3",
"postcss-url": "^7.3.2",
"prettier": "^1.14.3",
Expand Down
72 changes: 67 additions & 5 deletions packages/taro-cli/src/weapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ const t = require('babel-types')
const generate = require('babel-generator').default
const template = require('babel-template')
const autoprefixer = require('autoprefixer')
const minimatch = require('minimatch')
const _ = require('lodash')

const postcss = require('postcss')
const pxtransform = require('postcss-pxtransform')
const cssUrlParse = require('postcss-url')
const minimatch = require('minimatch')
const _ = require('lodash')
const Scope = require('postcss-modules-scope')
const Values = require('postcss-modules-values')
const genericNames = require('generic-names')
const LocalByDefault = require('postcss-modules-local-by-default')
const ExtractImports = require('postcss-modules-extract-imports')
const ResolveImports = require('postcss-modules-resolve-imports')

const Util = require('./util')
const CONFIG = require('./config')
Expand Down Expand Up @@ -359,6 +366,7 @@ function parseAst (type, ast, depComponents, sourceFilePath, filePath, npmSkip =
const node = astPath.node
const source = node.source
let value = source.value
const specifiers = node.specifiers
if (Util.isNpmPkg(value) && notExistNpmList.indexOf(value) < 0) {
if (value === taroJsComponents) {
astPath.remove()
Expand Down Expand Up @@ -403,6 +411,28 @@ function parseAst (type, ast, depComponents, sourceFilePath, filePath, npmSkip =
}
}
}
} else if (Util.CSS_EXT.indexOf(path.extname(value)) !== -1 && specifiers.length > 0) { // 对 使用 import style from './style.css' 语法引入的做转化处理
const specifiersName = specifiers[0].local.name
Util.printLog(Util.pocessTypeEnum.GENERATE, '替换代码', `为文件 ${sourceFilePath} 生成css-module`)
const styleFilePath = path.join(path.dirname(sourceFilePath), value)
const styleCode = fs.readFileSync(styleFilePath).toString()
const result = processStyleUseCssModule({
css: styleCode,
filePath: styleFilePath
})
const tokens = result.root.exports || {}
const objectPropperties = []
for (const key in tokens) {
if (tokens.hasOwnProperty(key)) {
objectPropperties.push(t.objectProperty(t.identifier(key), t.stringLiteral(tokens[key])))
}
}
astPath.replaceWith(
t.variableDeclaration('const', [t.variableDeclarator(t.identifier(specifiersName), t.objectExpression(objectPropperties))])
)
if (styleFiles.indexOf(styleFilePath) < 0) { // add this css file to queue
styleFiles.push(styleFilePath)
}
} else if (path.isAbsolute(value)) {
Util.printLog(Util.pocessTypeEnum.ERROR, '引用文件', `文件 ${sourceFilePath} 中引用 ${value} 是绝对路径!`)
}
Expand Down Expand Up @@ -1260,9 +1290,41 @@ async function buildSinglePage (page) {
}
}

/**
* css module processor
* @param styleObj { css: string, filePath: '' }
* @returns postcss.process()
*/
function processStyleUseCssModule (styleObj) {
// 对 xxx.global.[css|scss|less|styl] 等样式文件不做处理
const DO_NOT_USE_CSS_MODULE = '.global'
if (styleObj.filePath.indexOf(DO_NOT_USE_CSS_MODULE) > -1) return styleObj
const useModuleConf = weappConf.module || {}
const customPostcssConf = useModuleConf.postcss || {}
const generateScopedName = customPostcssConf.module.generateScopedName
const context = process.cwd()
let scopedName
if (generateScopedName) {
scopedName = genericNames(generateScopedName, { context })
} else {
scopedName = (local, filename) => Scope.generateScopedName(local, path.relative(context, filename))
}
const postcssPlugins = [
Values,
LocalByDefault,
ExtractImports,
new Scope({ generateScopedName: scopedName }),
new ResolveImports({ resolve: Object.assign({}, { extensions: Util.CSS_EXT }) }),
]
const runner = postcss(postcssPlugins)
const result = runner.process(styleObj.css, Object.assign({}, { from: styleObj.filePath }))
return result
}

async function processStyleWithPostCSS (styleObj) {
const useModuleConf = weappConf.module || {}
const customPostcssConf = useModuleConf.postcss || {}
const useCssModule = customPostcssConf.module
const customPxtransformConf = Object.assign({
enable: true,
config: {}
Expand Down Expand Up @@ -1304,9 +1366,9 @@ async function processStyleWithPostCSS (styleObj) {
encodeType: 'base64'
}))
}
const postcssResult = await postcss(processors).process(styleObj.css, {
from: styleObj.filePath
})
let css = styleObj.css
if (useCssModule) css = processStyleUseCssModule(styleObj).css
const postcssResult = await postcss(processors).process(css, { from: styleObj.filePath })
return postcssResult.css
}

Expand Down
3 changes: 3 additions & 0 deletions packages/taro-cli/templates/default/config/index
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const config = {
weapp: {
module: {
postcss: {
module: {
generateScopedName: '[name]__[local]___[hash:base64:5]',
},
autoprefixer: {
enable: true
},
Expand Down

0 comments on commit bc85775

Please sign in to comment.