@tarojs/rn-style-transformer 3.3.5 → 3.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,18 @@
1
1
  import fs from 'fs'
2
2
  import path from 'path'
3
3
  import sass, { Options } from 'sass'
4
- import { insertBefore, resolveStyle } from '../utils'
5
- import { TransformOptions } from '../types'
4
+ import { insertAfter, insertBefore, resolveStyle, getAdditionalData } from '../utils'
5
+ import { TransformOptions, RenderResult, RenderAdditionalResult } from '../types'
6
6
 
7
7
  // https://github.com/sass/node-sass#options
8
8
  export interface Config {
9
+ sass?: SassGlobalConfig
9
10
  alias?: Record<string, string>
10
11
  options?: Options
11
- additionalData?: string | ((string) => string)
12
+ additionalData?: string | ((key: string) => string)
12
13
  }
13
14
 
14
- export interface SassExternalConfig {
15
+ export interface SassGlobalConfig {
15
16
  resource?: string | string[];
16
17
  projectDirectory?: string;
17
18
  data?: string;
@@ -31,13 +32,7 @@ function makeImportStatement (filePath: string, resource: string, rootDir: strin
31
32
  return `@import '${relativePath}'`
32
33
  }
33
34
 
34
- /**
35
- * 处理 additional 配置,比如 config.sass 配置
36
- * @param src
37
- * @param filename
38
- * @returns
39
- */
40
- export function processByExternal (src, filename, config: SassExternalConfig) {
35
+ function getGlobalResource (filename: string, config: SassGlobalConfig) {
41
36
  let resource = ''
42
37
  const projectDirectory = config.projectDirectory || process.cwd()
43
38
  const filePath = path.dirname(path.resolve(projectDirectory, filename))
@@ -48,8 +43,18 @@ export function processByExternal (src, filename, config: SassExternalConfig) {
48
43
  const resources = config.resource?.map(source => makeImportStatement(filePath, source, projectDirectory)) || []
49
44
  resource = resources.join(';\n')
50
45
  }
51
- const combineSource = insertBefore(config?.data, resource)
52
- return insertBefore(src, combineSource)
46
+ // https://taro-docs.jd.com/taro/docs/config-detail/#sassdata, data 覆盖 resurce 配置
47
+ return insertAfter(resource, config?.data)
48
+ }
49
+
50
+ function combineResource (src: string, filename: string, config: Config) {
51
+ // sass config
52
+ const globalResource = getGlobalResource(filename, config.sass)
53
+
54
+ // sass tranform config
55
+ const additionalData = getAdditionalData(src, config.additionalData)
56
+
57
+ return insertAfter(globalResource, additionalData)
53
58
  }
54
59
 
55
60
  function renderToCSS (src, filename, options, transformOptions) {
@@ -81,8 +86,10 @@ function renderToCSS (src, filename, options, transformOptions) {
81
86
  defaultExt,
82
87
  alias: options.alias,
83
88
  platform: transformOptions.platform
84
- })
85
- return { file: file }
89
+ }
90
+ )
91
+ const contents = fs.readFileSync(file, 'utf8')
92
+ return { file, contents }
86
93
  } catch (err) {
87
94
  return err
88
95
  }
@@ -96,8 +103,7 @@ function renderToCSS (src, filename, options, transformOptions) {
96
103
  if (err) {
97
104
  reject(err)
98
105
  } else {
99
- const css = result.css.toString()
100
- resolve(css)
106
+ resolve(result)
101
107
  }
102
108
  })
103
109
  })
@@ -109,21 +115,25 @@ export default function transform (
109
115
  config: Config,
110
116
  transformOptions: TransformOptions
111
117
  ) {
112
- let data = src
118
+ const additionalData = combineResource(src, filename, config)
119
+ let data = insertBefore(src, additionalData)
113
120
 
114
121
  if (!data) {
115
122
  data = `\n${data}` // fix empty file error. reference https://github.com/sass/node-sass/blob/91c40a0bf0a3923ab9f91b82dcd479c25486235a/lib/index.js#L430
116
123
  }
117
124
 
118
- if (typeof config.additionalData !== 'undefined') {
119
- data =
120
- typeof config.additionalData === 'function'
121
- ? `${config.additionalData(data)}`
122
- : `${config.additionalData}\n${data}`
123
- }
124
-
125
- return renderToCSS(data, filename, { ...config.options, alias: config.alias }, transformOptions)
126
- .then((css: string) => {
127
- return css
128
- })
125
+ return renderToCSS(
126
+ data,
127
+ filename,
128
+ {
129
+ file: filename,
130
+ outFile: `${filename}.map`,
131
+ sourceMap: true, // If no outFile is set, sourceMap parameter is ignored.
132
+ alias: config.alias,
133
+ ...config.options
134
+ },
135
+ transformOptions
136
+ ).then((result: RenderResult) => {
137
+ return { ...result, additionalData } as RenderAdditionalResult
138
+ })
129
139
  }
@@ -1,4 +1,6 @@
1
1
  import stylus from 'stylus'
2
+ import { RenderResult, RenderAdditionalResult } from '../types'
3
+ import { getAdditionalData, insertBefore } from '../utils'
2
4
 
3
5
  class Evaluator { }
4
6
 
@@ -99,7 +101,7 @@ interface RenderOptions {
99
101
  export interface Config {
100
102
  alias?: Record<string, string>
101
103
  options: RenderOptions
102
- additionalData?: string | ((string) => string)
104
+ additionalData?: string | ((key: string) => string)
103
105
  }
104
106
 
105
107
  export const defaultOptions = {
@@ -118,6 +120,15 @@ function renderToCSS (src, filename, options = {} as RenderOptions) {
118
120
  const stylusOptions = { filename, ...options }
119
121
  const styl = stylus(src, stylusOptions)
120
122
 
123
+ styl.set(
124
+ 'sourcemap',
125
+ {
126
+ comment: true,
127
+ sourceRoot: '.', // stylusOptions.dest
128
+ basePath: '.'
129
+ }
130
+ )
131
+
121
132
  // include regular CSS on @import
122
133
  if (stylusOptions.includeCSS) {
123
134
  styl.set('include css', true)
@@ -191,23 +202,24 @@ function renderToCSS (src, filename, options = {} as RenderOptions) {
191
202
  if (err) {
192
203
  reject(err)
193
204
  } else {
194
- resolve(css)
205
+ resolve({
206
+ css,
207
+ map: styl.sourcemap
208
+ })
195
209
  }
196
210
  })
197
211
  })
198
212
  }
199
213
 
200
214
  export default function transform (src: string, filename: string, config: Config) {
201
- let data = src
202
-
203
- if (typeof config.additionalData !== 'undefined') {
204
- data =
205
- typeof config.additionalData === 'function'
206
- ? `${config.additionalData(data)}`
207
- : `${config.additionalData}\n${data}`
208
- }
209
- return renderToCSS(data, filename, config.options)
210
- .then((css: string) => {
211
- return css
212
- })
215
+ const additionalData = getAdditionalData(src, config.additionalData)
216
+ const data = insertBefore(src, additionalData)
217
+
218
+ return renderToCSS(
219
+ data,
220
+ filename,
221
+ config.options
222
+ ).then((result: RenderResult) => {
223
+ return { ...result, additionalData } as RenderAdditionalResult
224
+ })
213
225
  }
@@ -8,7 +8,7 @@ export interface TransformOptions {
8
8
  customTransformOptions: any
9
9
  }
10
10
 
11
- export enum LogLevelEnum {
11
+ export const enum LogLevelEnum {
12
12
  ERROR = 'error',
13
13
  WARNING = 'warning',
14
14
  }
@@ -21,3 +21,12 @@ export interface ResolveStyleOptions {
21
21
  defaultExt?: string
22
22
  alias?: Record<string, string>
23
23
  }
24
+
25
+ export interface RenderResult {
26
+ css: string | Buffer
27
+ map?: string | Buffer
28
+ }
29
+
30
+ export interface RenderAdditionalResult extends RenderResult {
31
+ additionalData: string
32
+ }
@@ -3,30 +3,30 @@ import path from 'path'
3
3
  import { printLog, processTypeEnum } from '@tarojs/helper'
4
4
  import { ResolveStyleOptions, LogLevelEnum } from '../types'
5
5
 
6
- export function insertBefore (source: string, target: string) {
7
- if (!source && !target) {
6
+ export function insertBefore (source: string, additional: string) {
7
+ if (!source && !additional) {
8
8
  return ''
9
9
  }
10
10
  if (!source) {
11
- return target
11
+ return additional
12
12
  }
13
- if (!target) {
13
+ if (!additional) {
14
14
  return source
15
15
  }
16
- return target + ';\n' + source
16
+ return additional + ';\n' + source
17
17
  }
18
18
 
19
- export function insertAfter (source: string, target: string) {
20
- if (!source && !target) {
19
+ export function insertAfter (source: string, additional: string) {
20
+ if (!source && !additional) {
21
21
  return ''
22
22
  }
23
23
  if (!source) {
24
- return target
24
+ return additional
25
25
  }
26
- if (!target) {
26
+ if (!additional) {
27
27
  return source
28
28
  }
29
- return source + ';\n' + target
29
+ return source + ';\n' + additional
30
30
  }
31
31
 
32
32
  // Iterate through the include paths and extensions to find the file variant
@@ -99,4 +99,83 @@ export function resolveStyle (id: string, opts: ResolveStyleOptions) {
99
99
  return file
100
100
  }
101
101
 
102
+ // copy from https://github.com/webpack-contrib/css-loader/blob/master/src/utils.js
103
+ const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i
104
+ const ABSOLUTE_SCHEME = /^[a-z0-9+\-.]+:/i
105
+
106
+ export function normalizePath (file) {
107
+ return path.sep === '\\' ? file.replace(/\\/g, '/') : file
108
+ }
109
+
110
+ function getURLType (source) {
111
+ if (source[0] === '/') {
112
+ if (source[1] === '/') {
113
+ return 'scheme-relative'
114
+ }
115
+
116
+ return 'path-absolute'
117
+ }
118
+
119
+ if (IS_NATIVE_WIN32_PATH.test(source)) {
120
+ return 'path-absolute'
121
+ }
122
+
123
+ return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative'
124
+ }
125
+
126
+ export function normalizeSourceMap (map, resourcePath) {
127
+ let newMap = map
128
+
129
+ // Some loader emit source map as string
130
+ // Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
131
+ if (typeof newMap === 'string') {
132
+ newMap = JSON.parse(newMap)
133
+ }
134
+
135
+ delete newMap.file
136
+
137
+ const { sourceRoot } = newMap
138
+
139
+ delete newMap.sourceRoot
140
+
141
+ if (newMap.sources) {
142
+ // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
143
+ // We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
144
+ newMap.sources = newMap.sources.map((source) => {
145
+ // Non-standard syntax from `postcss`
146
+ if (source.indexOf('<') === 0) {
147
+ return source
148
+ }
149
+
150
+ const sourceType = getURLType(source)
151
+
152
+ // Do no touch `scheme-relative` and `absolute` URLs
153
+ if (sourceType === 'path-relative' || sourceType === 'path-absolute') {
154
+ const absoluteSource =
155
+ sourceType === 'path-relative' && sourceRoot
156
+ ? path.resolve(sourceRoot, normalizePath(source))
157
+ : normalizePath(source)
158
+
159
+ return path.relative(path.dirname(resourcePath), absoluteSource)
160
+ }
161
+
162
+ return source
163
+ })
164
+ }
165
+
166
+ return newMap
167
+ }
168
+ // copy end
169
+
170
+ export function getAdditionalData (data: string, config: string | ((key: string) => string)) {
171
+ let additionalData = ''
172
+ if (typeof config !== 'undefined') {
173
+ additionalData =
174
+ typeof config === 'function'
175
+ ? `${config(data)}`
176
+ : config
177
+ }
178
+ return additionalData
179
+ }
180
+
102
181
  export default {}
@@ -0,0 +1,24 @@
1
+ interface Location {
2
+ line: number
3
+ column: number
4
+ file: string
5
+ }
6
+
7
+ export default function reporterSkip ({ skipRows, filename }) {
8
+ // @ts-ignore
9
+ return (css, result) => {
10
+ result.messages?.forEach((message: any) => {
11
+ const { line, column, node } = message
12
+
13
+ const messageInput = node?.source?.input
14
+ if (messageInput) {
15
+ const originLocation: Location = messageInput.origin(line, column)
16
+ // 如果是原始引入的样式文件,则对拼接的代码(addionalData)函数做减法
17
+ if (originLocation && originLocation.file.includes(filename)) {
18
+ // force modify line,then source map cannot read origin column, value is 0.
19
+ message.line -= skipRows
20
+ }
21
+ }
22
+ })
23
+ }
24
+ }