@mpxjs/webpack-plugin 2.8.40-beta.0 → 2.8.40-test.2

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.
Files changed (63) hide show
  1. package/lib/dependencies/CommonJsExtractDependency.js +51 -0
  2. package/lib/dependencies/DynamicEntryDependency.js +10 -16
  3. package/lib/dependencies/ResolveDependency.js +11 -20
  4. package/lib/extractor.js +1 -0
  5. package/lib/helpers.js +9 -1
  6. package/lib/index.js +239 -134
  7. package/lib/json-compiler/helper.js +27 -17
  8. package/lib/json-compiler/index.js +82 -31
  9. package/lib/loader.js +31 -37
  10. package/lib/native-loader.js +21 -14
  11. package/lib/parser.js +0 -1
  12. package/lib/platform/index.js +15 -4
  13. package/lib/platform/json/wx/index.js +63 -2
  14. package/lib/platform/run-rules.js +1 -1
  15. package/lib/platform/template/normalize-component-rules.js +42 -41
  16. package/lib/platform/template/wx/component-config/README.md +1 -1
  17. package/lib/platform/template/wx/component-config/component.js +1 -2
  18. package/lib/platform/template/wx/component-config/fix-component-name.js +21 -0
  19. package/lib/platform/template/wx/component-config/hypen-tag-name.js +2 -6
  20. package/lib/platform/template/wx/component-config/index.js +6 -4
  21. package/lib/platform/template/wx/component-config/view.js +0 -11
  22. package/lib/platform/template/wx/index.js +84 -32
  23. package/lib/runtime/base.styl +9 -6
  24. package/lib/runtime/components/web/filterTag.js +9 -30
  25. package/lib/runtime/components/web/getInnerListeners.js +3 -16
  26. package/lib/runtime/components/web/mpx-image.vue +13 -10
  27. package/lib/runtime/components/web/mpx-keep-alive.vue +10 -17
  28. package/lib/runtime/components/web/mpx-movable-view.vue +105 -23
  29. package/lib/runtime/components/web/mpx-picker-view-column.vue +10 -2
  30. package/lib/runtime/components/web/mpx-picker-view.vue +1 -1
  31. package/lib/runtime/components/web/mpx-picker.vue +9 -1
  32. package/lib/runtime/components/web/mpx-scroll-view.vue +69 -23
  33. package/lib/runtime/components/web/mpx-swiper.vue +152 -62
  34. package/lib/runtime/components/web/mpx-video.vue +123 -89
  35. package/lib/runtime/components/web/mpx-web-view.vue +120 -81
  36. package/lib/runtime/components/web/promisify.js +19 -0
  37. package/lib/runtime/components/wx/default-page.mpx +27 -0
  38. package/lib/runtime/optionProcessor.js +321 -270
  39. package/lib/runtime/stringify.wxs +44 -8
  40. package/lib/style-compiler/index.js +6 -3
  41. package/lib/template-compiler/bind-this.js +280 -49
  42. package/lib/template-compiler/compiler.js +122 -108
  43. package/lib/template-compiler/index.js +35 -23
  44. package/lib/utils/check-core-version-match.js +18 -14
  45. package/lib/utils/dom-tag-config.js +115 -0
  46. package/lib/utils/make-map.js +12 -0
  47. package/lib/utils/string.js +7 -1
  48. package/lib/utils/ts-loader-watch-run-loader-filter.js +4 -5
  49. package/lib/web/processJSON.js +39 -3
  50. package/lib/web/processMainScript.js +84 -0
  51. package/lib/web/processScript.js +21 -201
  52. package/lib/web/processTemplate.js +11 -35
  53. package/lib/web/script-helper.js +202 -0
  54. package/package.json +7 -6
  55. package/lib/json-compiler/default-page.mpx +0 -3
  56. package/lib/style-compiler/plugins/trim.js +0 -15
  57. package/lib/template-compiler/preprocessor.js +0 -29
  58. package/lib/wxss/compile-exports.js +0 -52
  59. package/lib/wxss/createResolver.js +0 -36
  60. package/lib/wxss/css-base.js +0 -79
  61. package/lib/wxss/getLocalIdent.js +0 -25
  62. package/lib/wxss/localsLoader.js +0 -44
  63. package/lib/wxss/processCss.js +0 -274
@@ -2,23 +2,7 @@ const templateCompiler = require('../template-compiler/compiler')
2
2
  const genComponentTag = require('../utils/gen-component-tag')
3
3
  const addQuery = require('../utils/add-query')
4
4
  const parseRequest = require('../utils/parse-request')
5
- // const { matchCondition } = require('../utils/match-condition')
6
-
7
- function calculateRootEleChild (arr) {
8
- if (!arr) {
9
- return 0
10
- }
11
- return arr.reduce((total, item) => {
12
- if (item.type === 1) {
13
- if (item.tag === 'template') {
14
- total += calculateRootEleChild(item.children)
15
- } else {
16
- total += 1
17
- }
18
- }
19
- return total
20
- }, 0)
21
- }
5
+ const { matchCondition } = require('../utils/match-condition')
22
6
 
23
7
  module.exports = function (template, {
24
8
  loaderContext,
@@ -38,8 +22,9 @@ module.exports = function (template, {
38
22
  wxsContentMap,
39
23
  decodeHTMLText,
40
24
  externalClasses,
41
- checkUsingComponents
42
- // autoVirtualHostRules
25
+ checkUsingComponents,
26
+ webConfig,
27
+ autoVirtualHostRules
43
28
  } = mpx
44
29
  const { resourcePath } = parseRequest(loaderContext.resource)
45
30
  const builtInComponentsMap = {}
@@ -48,9 +33,11 @@ module.exports = function (template, {
48
33
  let output = '/* template */\n'
49
34
 
50
35
  if (ctorType === 'app') {
36
+ const { el } = webConfig
37
+ const idName = el?.match(/#(.*)/)?.[1] || 'app'
51
38
  template = {
52
39
  tag: 'template',
53
- content: '<div class="app"><mpx-keep-alive><router-view class="page"></router-view></mpx-keep-alive></div>'
40
+ content: `<div id="${idName}"><mpx-keep-alive><router-view></router-view></mpx-keep-alive></div>`
54
41
  }
55
42
  builtInComponentsMap['mpx-keep-alive'] = {
56
43
  resource: addQuery('@mpxjs/webpack-plugin/lib/runtime/components/web/mpx-keep-alive.vue', { isComponent: true })
@@ -72,6 +59,7 @@ module.exports = function (template, {
72
59
  }
73
60
  if (template.content) {
74
61
  const templateSrcMode = template.mode || srcMode
62
+
75
63
  const { root, meta } = templateCompiler.parse(template.content, {
76
64
  warn: (msg) => {
77
65
  loaderContext.emitWarning(
@@ -87,6 +75,7 @@ module.exports = function (template, {
87
75
  hasComment,
88
76
  isNative,
89
77
  isComponent: ctorType === 'component',
78
+ isPage: ctorType === 'page',
90
79
  mode,
91
80
  srcMode: templateSrcMode,
92
81
  defs,
@@ -101,9 +90,8 @@ module.exports = function (template, {
101
90
  // web模式下全局组件不会被合入usingComponents中,故globalComponents可以传空
102
91
  globalComponents: [],
103
92
  // web模式下实现抽象组件
104
- componentGenerics
105
- // todo 后续输出web也基于autoVirtualHostRules决定是否添加root wrapper
106
- // hasVirtualHost: matchCondition(resourcePath, autoVirtualHostRules)
93
+ componentGenerics,
94
+ hasVirtualHost: matchCondition(resourcePath, autoVirtualHostRules)
107
95
  })
108
96
  if (meta.wxsModuleMap) {
109
97
  wxsModuleMap = meta.wxsModuleMap
@@ -123,18 +111,6 @@ module.exports = function (template, {
123
111
  if (meta.genericsInfo) {
124
112
  genericsInfo = meta.genericsInfo
125
113
  }
126
- // 输出H5有多个root element时, 使用mpx-root-view标签包裹
127
- // todo 后续输出web也基于autoVirtualHostRules决定是否添加root wrapper
128
- if (root.tag === 'temp-node') {
129
- const childLen = calculateRootEleChild(root.children)
130
- if (childLen >= 2) {
131
- root.tag = 'div'
132
- templateCompiler.addAttrs(root, [{
133
- name: 'class',
134
- value: 'mpx-root-view'
135
- }])
136
- }
137
- }
138
114
  return templateCompiler.serialize(root)
139
115
  }
140
116
  })
@@ -0,0 +1,202 @@
1
+ const hasOwn = require('../utils/has-own')
2
+ const loaderUtils = require('loader-utils')
3
+ const normalize = require('../utils/normalize')
4
+ const createHelpers = require('../helpers')
5
+ const tabBarContainerPath = normalize.lib('runtime/components/web/mpx-tab-bar-container.vue')
6
+ const tabBarPath = normalize.lib('runtime/components/web/mpx-tab-bar.vue')
7
+ const addQuery = require('../utils/add-query')
8
+
9
+ function stringifyRequest (loaderContext, request) {
10
+ return loaderUtils.stringifyRequest(loaderContext, request)
11
+ }
12
+
13
+ function shallowStringify (obj) {
14
+ const arr = []
15
+ for (const key in obj) {
16
+ if (hasOwn(obj, key)) {
17
+ let value = obj[key]
18
+ if (Array.isArray(value)) {
19
+ value = `[${value.join(',')}]`
20
+ }
21
+ arr.push(`'${key}':${value}`)
22
+ }
23
+ }
24
+ return `{${arr.join(',')}}`
25
+ }
26
+
27
+ function getAsyncChunkName (chunkName) {
28
+ if (chunkName && typeof chunkName !== 'boolean') {
29
+ return `/* webpackChunkName: "${chunkName}" */`
30
+ }
31
+ return ''
32
+ }
33
+
34
+ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderContext }) {
35
+ const componentsMap = {}
36
+ if (localComponentsMap) {
37
+ Object.keys(localComponentsMap).forEach((componentName) => {
38
+ const componentCfg = localComponentsMap[componentName]
39
+ const componentRequest = stringifyRequest(loaderContext, componentCfg.resource)
40
+ if (componentCfg.async) {
41
+ componentsMap[componentName] = `()=>import(${getAsyncChunkName(componentCfg.async)}${componentRequest}).then(res => getComponent(res))`
42
+ } else {
43
+ componentsMap[componentName] = `getComponent(require(${componentRequest}))`
44
+ }
45
+ })
46
+ }
47
+ if (builtInComponentsMap) {
48
+ Object.keys(builtInComponentsMap).forEach((componentName) => {
49
+ const componentCfg = builtInComponentsMap[componentName]
50
+ const componentRequest = stringifyRequest(loaderContext, componentCfg.resource)
51
+ componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
52
+ })
53
+ }
54
+ return componentsMap
55
+ }
56
+
57
+ function buildPagesMap ({ localPagesMap, loaderContext, tabBar, tabBarMap, tabBarStr, jsonConfig }) {
58
+ let globalTabBar = ''
59
+ let firstPage = ''
60
+ const pagesMap = {}
61
+ const tabBarPagesMap = {}
62
+ if (tabBar && tabBarMap) {
63
+ // 挂载tabBar组件
64
+ const tabBarRequest = stringifyRequest(loaderContext, addQuery(tabBar.custom ? './custom-tab-bar/index' : tabBarPath, { isComponent: true }))
65
+ tabBarPagesMap['mpx-tab-bar'] = `getComponent(require(${tabBarRequest}))`
66
+ // 挂载tabBar页面
67
+ Object.keys(tabBarMap).forEach((pagePath) => {
68
+ const pageCfg = localPagesMap[pagePath]
69
+ if (pageCfg) {
70
+ const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
71
+ if (pageCfg.async) {
72
+ tabBarPagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)}${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
73
+ } else {
74
+ tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
75
+ }
76
+ } else {
77
+ loaderContext.emitWarning(
78
+ new Error('[json processor][' + loaderContext.resource + ']: ' + `TabBar page path ${pagePath} is not exist in local page map, please check!`)
79
+ )
80
+ }
81
+ })
82
+ }
83
+ if (tabBarStr && tabBarPagesMap) {
84
+ globalTabBar += `
85
+ global.__tabBar = ${tabBarStr}
86
+ Vue.observable(global.__tabBar)
87
+ // @ts-ignore
88
+ global.__tabBarPagesMap = ${shallowStringify(tabBarPagesMap)}\n`
89
+ }
90
+ Object.keys(localPagesMap).forEach((pagePath) => {
91
+ const pageCfg = localPagesMap[pagePath]
92
+ const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
93
+ if (tabBarMap && tabBarMap[pagePath]) {
94
+ pagesMap[pagePath] = `getComponent(require(${stringifyRequest(loaderContext, tabBarContainerPath)}), { __mpxBuiltIn: true })`
95
+ } else {
96
+ if (pageCfg.async) {
97
+ pagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)} ${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
98
+ } else {
99
+ // 为了保持小程序中app->page->component的js执行顺序,所有的page和component都改为require引入
100
+ pagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
101
+ }
102
+ }
103
+
104
+ if (pagePath === jsonConfig.entryPagePath) {
105
+ firstPage = pagePath
106
+ }
107
+ if (!firstPage && pageCfg.isFirst) {
108
+ firstPage = pagePath
109
+ }
110
+ })
111
+ return {
112
+ pagesMap,
113
+ firstPage,
114
+ globalTabBar
115
+ }
116
+ }
117
+
118
+ function getRequireScript ({ ctorType, script, loaderContext }) {
119
+ let content = ' /** script content **/\n'
120
+ const extraOptions = { ctorType, lang: script.lang || 'js' }
121
+ const { getRequire } = createHelpers(loaderContext)
122
+ content += ` ${getRequire('script', script, extraOptions)}\n`
123
+ return content
124
+ }
125
+
126
+ function buildGlobalParams ({ moduleId, scriptSrcMode, loaderContext, isProduction, jsonConfig, webConfig, isMain, globalTabBar }) {
127
+ let content = ''
128
+ if (isMain) {
129
+ content += `
130
+ global.getApp = function(){}
131
+ global.getCurrentPages = function () {
132
+ if (!(typeof window !== 'undefined')) {
133
+ console.error('[Mpx runtime error]: Dangerous API! global.getCurrentPages is running in non browser environment, It may cause some problems, please use this method with caution')
134
+ }
135
+ const router = global.__mpxRouter
136
+ if(!router) return []
137
+ // @ts-ignore
138
+ return (router.lastStack || router.stack).map(item => {
139
+ let page
140
+ const vnode = item.vnode
141
+ if (vnode && vnode.componentInstance) {
142
+ page = vnode.tag.endsWith('mpx-tab-bar-container') ? vnode.componentInstance.$refs.tabBarPage : vnode.componentInstance
143
+ }
144
+ return page || { route: item.path.slice(1) }
145
+ })
146
+ }
147
+ global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
148
+ global.__mpxGenericsMap = {}
149
+ global.__mpxOptionsMap = {}
150
+ global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
151
+ global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}
152
+ global.__mpxTransRpxFn = ${webConfig.transRpxFn}\n`
153
+ if (globalTabBar) {
154
+ content += globalTabBar
155
+ }
156
+ }
157
+ content += ` global.currentModuleId = ${JSON.stringify(moduleId)}\n`
158
+ content += ` global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
159
+ content += ` global.currentInject = ${JSON.stringify({ moduleId })}\n`
160
+ if (!isProduction) {
161
+ content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
162
+ }
163
+ return content
164
+ }
165
+
166
+ function buildI18n ({ i18n, loaderContext }) {
167
+ let i18nContent = ''
168
+ const i18nObj = Object.assign({}, i18n)
169
+ i18nContent += `
170
+ import VueI18n from 'vue-i18n'
171
+ import { createI18n } from 'vue-i18n-bridge'
172
+ Vue.use(VueI18n , { bridge: true })\n`
173
+ const requestObj = {}
174
+ const i18nKeys = ['messages', 'dateTimeFormats', 'numberFormats']
175
+ i18nKeys.forEach((key) => {
176
+ if (i18nObj[`${key}Path`]) {
177
+ requestObj[key] = stringifyRequest(loaderContext, i18nObj[`${key}Path`])
178
+ delete i18nObj[`${key}Path`]
179
+ }
180
+ })
181
+ i18nContent += ` const i18nCfg = ${JSON.stringify(i18nObj)}\n`
182
+ Object.keys(requestObj).forEach((key) => {
183
+ i18nContent += ` i18nCfg.${key} = require(${requestObj[key]})\n`
184
+ })
185
+ i18nContent += `
186
+ i18nCfg.legacy = false
187
+ const i18n = createI18n(i18nCfg, VueI18n)
188
+ Vue.use(i18n)
189
+ Mpx.i18n = i18n\n`
190
+ return i18nContent
191
+ }
192
+
193
+ module.exports = {
194
+ buildPagesMap,
195
+ buildComponentsMap,
196
+ getRequireScript,
197
+ buildGlobalParams,
198
+ shallowStringify,
199
+ getAsyncChunkName,
200
+ stringifyRequest,
201
+ buildI18n
202
+ }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.8.40-beta.0",
3
+ "version": "2.8.40-test.2",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
7
7
  ],
8
8
  "author": "donghongping",
9
- "license": "Apache",
9
+ "license": "Apache-2.0",
10
10
  "main": "lib/index.js",
11
11
  "directories": {
12
12
  "lib": "lib"
@@ -29,7 +29,6 @@
29
29
  "@better-scroll/zoom": "^2.5.1",
30
30
  "acorn-walk": "^7.2.0",
31
31
  "async": "^2.6.0",
32
- "consolidate": "^0.15.1",
33
32
  "css": "^2.2.1",
34
33
  "css-selector-tokenizer": "^0.7.0",
35
34
  "cssnano": "^5.0.16",
@@ -55,10 +54,12 @@
55
54
  "postcss-modules-values": "^4.0.0",
56
55
  "postcss-selector-parser": "^6.0.8",
57
56
  "postcss-value-parser": "^4.0.2",
58
- "source-list-map": "^2.0.0"
57
+ "semver": "^7.5.4",
58
+ "source-list-map": "^2.0.0",
59
+ "video.js": "^8.6.0"
59
60
  },
60
61
  "peerDependencies": {
61
- "webpack": "^5.48.0"
62
+ "webpack": "^5.75.0"
62
63
  },
63
64
  "publishConfig": {
64
65
  "registry": "https://registry.npmjs.org",
@@ -82,5 +83,5 @@
82
83
  "engines": {
83
84
  "node": ">=14.14.0"
84
85
  },
85
- "gitHead": "03d5373a8526f23e00f05917aaf84f6fbb7ef98f"
86
+ "gitHead": "7b1911025a2eb47eddc046775f17b6f1405fdd54"
86
87
  }
@@ -1,3 +0,0 @@
1
- <template>
2
- <view>局部构建兜底页面</view>
3
- </template>
@@ -1,15 +0,0 @@
1
-
2
- module.exports = (opts) => {
3
- return {
4
- postcssPlugin: 'trim',
5
- Once: (root) => {
6
- root.walk(({ type, raws }) => {
7
- if (type === 'rule' || type === 'atrule') {
8
- raws.before = raws.after = '\n'
9
- }
10
- })
11
- }
12
- }
13
- }
14
-
15
- module.exports.postcss = true
@@ -1,29 +0,0 @@
1
- // loader for pre-processing templates with e.g. pug
2
-
3
- const cons = require('consolidate')
4
- const loaderUtils = require('loader-utils')
5
-
6
- module.exports = function (content) {
7
- this.cacheable && this.cacheable()
8
- const callback = this.async()
9
- const opt = loaderUtils.getOptions(this) || {}
10
-
11
- if (!cons[opt.engine]) {
12
- return callback(new Error(
13
- 'Template engine \'' + opt.engine + '\' ' +
14
- 'isn\'t available in Consolidate.js'
15
- ))
16
- }
17
-
18
- const templateOption = opt.templateOption
19
-
20
- // for relative includes
21
- templateOption.filename = this.resourcePath
22
-
23
- cons[opt.engine].render(content, templateOption, function (err, html) {
24
- if (err) {
25
- return callback(err)
26
- }
27
- callback(null, html)
28
- })
29
- }
@@ -1,52 +0,0 @@
1
- const camelCase = require('lodash.camelcase')
2
-
3
- function dashesCamelCase (str) {
4
- return str.replace(/-+(\w)/g, function (match, firstLetter) {
5
- return firstLetter.toUpperCase()
6
- })
7
- }
8
-
9
- module.exports = function compileExports (result, importItemMatcher, camelCaseKeys) {
10
- if (!Object.keys(result.exports).length) {
11
- return ''
12
- }
13
-
14
- const exportJs = Object.keys(result.exports).reduce(function (res, key) {
15
- let valueAsString = JSON.stringify(result.exports[key])
16
- valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher)
17
-
18
- function addEntry (k) {
19
- res.push('\t' + JSON.stringify(k) + ': ' + valueAsString)
20
- }
21
-
22
- let targetKey
23
- switch (camelCaseKeys) {
24
- case true:
25
- addEntry(key)
26
- targetKey = camelCase(key)
27
- if (targetKey !== key) {
28
- addEntry(targetKey)
29
- }
30
- break
31
- case 'dashes':
32
- addEntry(key)
33
- targetKey = dashesCamelCase(key)
34
- if (targetKey !== key) {
35
- addEntry(targetKey)
36
- }
37
- break
38
- case 'only':
39
- addEntry(camelCase(key))
40
- break
41
- case 'dashesOnly':
42
- addEntry(dashesCamelCase(key))
43
- break
44
- default:
45
- addEntry(key)
46
- break
47
- }
48
- return res
49
- }, []).join(',\n')
50
-
51
- return '{\n' + exportJs + '\n}'
52
- }
@@ -1,36 +0,0 @@
1
- module.exports = function createResolver (alias) {
2
- if (typeof alias !== 'object' || Array.isArray(alias)) {
3
- return function (url) {
4
- return url
5
- }
6
- }
7
-
8
- alias = Object.keys(alias).map(function (key) {
9
- let onlyModule = false
10
- let obj = alias[key]
11
- if (/\$$/.test(key)) {
12
- onlyModule = true
13
- key = key.substr(0, key.length - 1)
14
- }
15
- if (typeof obj === 'string') {
16
- obj = {
17
- alias: obj
18
- }
19
- }
20
- obj = Object.assign({
21
- name: key,
22
- onlyModule: onlyModule
23
- }, obj)
24
- return obj
25
- })
26
-
27
- return function (url) {
28
- alias.forEach(function (obj) {
29
- const name = obj.name
30
- if (url === name || (!obj.onlyModule && url.startsWith(name + '/'))) {
31
- url = obj.alias + url.substr(name.length)
32
- }
33
- })
34
- return url
35
- }
36
- }
@@ -1,79 +0,0 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- Modified by @hiyuki
5
- */
6
- // css base code, injected by the css-loader
7
- module.exports = function (useSourceMap) {
8
- const list = []
9
-
10
- // return the list of modules as css string
11
- list.toString = function toString () {
12
- return this.map(function (item) {
13
- const content = cssWithMappingToString(item, useSourceMap)
14
- if (item[2]) {
15
- return '@media ' + item[2] + '{' + content + '}'
16
- } else {
17
- return content
18
- }
19
- }).join('')
20
- }
21
-
22
- // import a list of modules into the list
23
- list.i = function (modules, mediaQuery) {
24
- if (typeof modules === 'string') {
25
- modules = [[null, modules, '']]
26
- }
27
- const alreadyImportedModules = {}
28
- for (let i = 0; i < this.length; i++) {
29
- const id = this[i][0]
30
- if (typeof id === 'number') {
31
- alreadyImportedModules[id] = true
32
- }
33
- }
34
- for (let i = 0; i < modules.length; i++) {
35
- const item = modules[i]
36
- // skip already imported module
37
- // this implementation is not 100% perfect for weird media query combinations
38
- // when a module is imported multiple times with different media queries.
39
- // I hope this will never occur (Hey this way we have smaller bundles)
40
- if (typeof item[0] !== 'number' || !alreadyImportedModules[item[0]]) {
41
- if (mediaQuery && !item[2]) {
42
- item[2] = mediaQuery
43
- } else if (mediaQuery) {
44
- item[2] = '(' + item[2] + ') and (' + mediaQuery + ')'
45
- }
46
- list.push(item)
47
- }
48
- }
49
- }
50
- return list
51
- }
52
-
53
- function cssWithMappingToString (item, useSourceMap) {
54
- const content = item[1] || ''
55
- const cssMapping = item[3]
56
- if (!cssMapping) {
57
- return content
58
- }
59
-
60
- if (useSourceMap && typeof btoa === 'function') {
61
- const sourceMapping = toComment(cssMapping)
62
- const sourceURLs = cssMapping.sources.map(function (source) {
63
- return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
64
- })
65
-
66
- return [content].concat(sourceURLs).concat([sourceMapping]).join('\n')
67
- }
68
-
69
- return [content].join('\n')
70
- }
71
-
72
- // Adapted from convert-source-map (MIT)
73
- function toComment (sourceMap) {
74
- // eslint-disable-next-line no-undef
75
- const base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))))
76
- const data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64
77
-
78
- return '/*# ' + data + ' */'
79
- }
@@ -1,25 +0,0 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- Modified by @hiyuki
5
- */
6
- const loaderUtils = require('loader-utils')
7
- const path = require('path')
8
-
9
- module.exports = function getLocalIdent (loaderContext, localIdentName, localName, options) {
10
- if (!options.context) {
11
- if (loaderContext.rootContext) {
12
- options.context = loaderContext.rootContext
13
- } else if (loaderContext.options && typeof loaderContext.options.context === 'string') {
14
- options.context = loaderContext.options.context
15
- } else {
16
- options.context = loaderContext.context
17
- }
18
- }
19
- const request = path.relative(options.context, loaderContext.resourcePath)
20
- options.content = options.hashPrefix + request + '+' + localName
21
- localIdentName = localIdentName.replace(/\[local\]/gi, localName)
22
- const hash = loaderUtils.interpolateName(loaderContext, localIdentName, options)
23
- /* eslint-disable prefer-regex-literals */
24
- return hash.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-').replace(/^((-?[0-9])|--)/, '_$1')
25
- }
@@ -1,44 +0,0 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- Modified by @hiyuki
5
- */
6
- const loaderUtils = require('loader-utils')
7
- const processCss = require('./processCss')
8
- const compileExports = require('./compile-exports')
9
- const createResolver = require('./createResolver')
10
-
11
- module.exports = function (content) {
12
- if (this.cacheable) this.cacheable()
13
- const callback = this.async()
14
- const query = loaderUtils.getOptions(this) || {}
15
- const moduleMode = query.modules || query.module
16
- const camelCaseKeys = query.camelCase || query.camelcase
17
- const resolve = createResolver(query.alias)
18
-
19
- processCss(content, null, {
20
- mode: moduleMode ? 'local' : 'global',
21
- query: query,
22
- minimize: this.minimize,
23
- loaderContext: this,
24
- resolve: resolve
25
- }, function (err, result) {
26
- if (err) return callback(err)
27
-
28
- function importItemMatcher (item) {
29
- const match = result.importItemRegExp.exec(item)
30
- const idx = +match[1]
31
- const importItem = result.importItems[idx]
32
- const importUrl = importItem.url
33
- return '" + require(' + loaderUtils.stringifyRequest(this, importUrl) + ')' +
34
- '[' + JSON.stringify(importItem.export) + '] + "'
35
- }
36
-
37
- let exportJs = compileExports(result, importItemMatcher.bind(this), camelCaseKeys)
38
- if (exportJs) {
39
- exportJs = 'module.exports = ' + exportJs + ';'
40
- }
41
-
42
- callback(null, exportJs)
43
- }.bind(this))
44
- }