UNPKG

8.05 kBJavaScriptView Raw
1/* global
2 __KOOT_LOCALEID__: false,
3*/
4
5const fs = require('fs-extra');
6const path = require('path');
7
8const getI18nType = require('../i18n/get-type');
9const getPublicPath = require('./get-public-dir');
10const getChunkmap = require('./get-chunkmap');
11
12/**
13 * 获指定文件在客户端/取浏览器端中的可访问路径
14 * @param {String} filename 要查找的文件的文件名。根据打包文件对应表 (chunkmap) 查询文件名和实际打包结果文件的对应关系
15 * @param {String} [localeId] 当前语言
16 * @param {Boolean} [isPathname = false] 如果标记为 true,表示提供的 filename 为确切的访问地址,无需查询对照表,直接返回结果
17 * @returns {String|String[]} 浏览器环境中的访问路径、空字符串或包含所有可能结果的 Array
18 */
19const getFilePath = (filename, localeId, isPathname = false) => {
20 // 如果第一个参数为 true,表示标记为 pathname
21 if (filename === true)
22 return getFilePath(localeId, isPathname || undefined, true);
23
24 if (typeof localeId === 'undefined') {
25 try {
26 if (
27 typeof __KOOT_SPA_TEMPLATE_INJECT__ === 'boolean' &&
28 __KOOT_SPA_TEMPLATE_INJECT__
29 ) {
30 localeId = __KOOT_LOCALEID__ || undefined;
31 } else {
32 localeId = require('../index').localeId;
33 }
34 } catch (e) {
35 // console.error(e);
36 }
37 }
38
39 const pathPublic = getPublicPath();
40
41 const i18nType = getI18nType();
42 const isI18nDefault = i18nType === 'default';
43 const isDev =
44 process.env.WEBPACK_BUILD_ENV === 'dev' ||
45 (typeof __DEV__ !== 'undefined' && __DEV__);
46 // const localeId = 'zh'
47
48 // 如果标记为 pathname,直接返回结果
49 if (isPathname)
50 return (
51 pathPublic +
52 filename.replace(
53 new RegExp(
54 '(^\\.\\/|^)public\\/' +
55 (process.env.KOOT_CLIENT_BUNDLE_SUBFOLDER
56 ? `${process.env.KOOT_CLIENT_BUNDLE_SUBFOLDER}\\/`
57 : '')
58 ),
59 ''
60 )
61 );
62
63 const chunkmap = getChunkmap(localeId);
64 const regPublicPath = chunkmap['.public']
65 ? new RegExp(`(^\\.\\/|^)${chunkmap['.public']}`)
66 : /(^\.\/|^)public\//;
67
68 /**************************************************************************
69 * ┌─┐┌─┐┌┬┐┌┬┐┌─┐┌┐┌ ┌─┐┬ ┬┌┐┌┌─┐┌┬┐┬┌─┐┌┐┌┌─┐
70 * │ │ ││││││││ ││││ ├┤ │ │││││ │ ││ ││││└─┐
71 * └─┘└─┘┴ ┴┴ ┴└─┘┘└┘ └ └─┘┘└┘└─┘ ┴ ┴└─┘┘└┘└─┘
72 *************************************************************************/
73
74 /**
75 * 返回可供客户端/浏览器端使用的访问地址
76 * @param {String} pathname
77 * @returns {String}
78 */
79 const getResultPathname = pathname =>
80 pathPublic + pathname.replace(regPublicPath, '');
81
82 /**************************************************************************
83 * ┌┬┐┌─┐┌┐ ┬ ┬┌─┐
84 * ││├┤ ├┴┐│ ││ ┬
85 * ─┴┘└─┘└─┘└─┘└─┘
86 *************************************************************************/
87
88 // console.log('----------')
89 // console.log(filename)
90 // console.log(chunkmap)
91 // console.log(chunkmap['.files'])
92 // console.log(chunkmap['.files'][filename])
93 // console.log(regPublicPath)
94 // console.log(pathPublic + chunkmap['.files'][filename].replace(regPublicPath, ''))
95 // console.log({
96 // regPublicPath,
97 // 'process.env.KOOT_CLIENT_BUNDLE_SUBFOLDER': process.env.KOOT_CLIENT_BUNDLE_SUBFOLDER
98 // })
99 // console.log('----------')
100
101 /**************************************************************************
102 * ┌─┐┬ ┬┌─┐┌─┐┬┌─ ┬ ┬─┐┌─┐┌┬┐┬─┐┬ ┬┌┐┌┌─┐
103 * │ ├─┤├┤ │ ├┴┐ ┌┼─ ├┬┘├┤ │ ├┬┘│ ││││└─┐
104 * └─┘┴ ┴└─┘└─┘┴ ┴ └┘ ┴└─└─┘ ┴ ┴└─└─┘┘└┘└─┘
105 *************************************************************************/
106
107 // 检查 `.files` 下是否有该文件名的直接对应
108 // 如果有,直接返回该结果
109 if (
110 typeof chunkmap === 'object' &&
111 typeof chunkmap['.files'] === 'object' &&
112 typeof chunkmap['.files'][filename] === 'string'
113 ) {
114 return getResultPathname(chunkmap['.files'][filename]);
115 }
116 if (isDev) {
117 const prefix = pathPublic + (isI18nDefault ? localeId : '');
118 if (
119 typeof chunkmap['.files'] === 'object' &&
120 typeof chunkmap['.files'][filename] === 'string'
121 )
122 return prefix + chunkmap['.files'][filename];
123 return prefix + `.${filename}`;
124 }
125
126 /** @type {String} 目标文件的扩展名 */
127 const extname = path.extname(filename);
128 /** @type {String} 目标文件的文件名(不包括扩展名) */
129 const basename = path.basename(filename, extname);
130
131 // 检查 `.entrypoints` 下是否有该文件的文件名对应(不包括扩展名)
132 // 如果有,同时只有一个结果,返回该结果
133 // 如果有,同时有多个结果,返回包含所有结果的 Array
134 if (Array.isArray(chunkmap['.entrypoints'][basename])) {
135 const files = chunkmap['.entrypoints'][basename].filter(
136 file => path.extname(file) === extname
137 );
138 if (files.length === 1) return getResultPathname(files[0]);
139 else if (files.length)
140 return files.map(file => getResultPathname(file));
141 }
142
143 // 检查 chunkmap 第一级是否有包含该文件的文件名的对应(不包括扩展名)
144 // 如果有,直接返回该结果
145 if (typeof chunkmap === 'object') {
146 let result;
147 if (Array.isArray(chunkmap[basename])) {
148 chunkmap[basename].some(value => {
149 if (path.extname(value) === extname) {
150 result = value;
151 return true;
152 }
153 return false;
154 });
155 }
156 if (result) return getResultPathname(result);
157 }
158
159 // 如果没有找到 chunkmap 或是 chunkmap 中未找到目标项目,转为过滤文件形式
160 if (fs.existsSync(path.resolve(pathPublic, filename))) {
161 return '/' + filename;
162 }
163
164 console.warn(
165 `File not found:` +
166 (isI18nDefault ? `[${localeId}] ` : '') +
167 ` ${filename}`
168 );
169
170 return '';
171
172 // const segs = pathname.split('/').filter(seg => seg !== '/')
173 // const file = segs.pop()
174 // const dir = segs.length ? `${segs.join('/')}/` : ''
175 // return `/${dir}${
176 // require('./filterTargetFile')(
177 // require('./readFilesInPath')(`./${distPathname}/public/${appName ? `${appName}/` : ''}${dir}`),
178 // file
179 // )}`
180};
181
182module.exports = getFilePath;
183// module.exports = (pathname, pathDist = 'dist') => {
184// if (__DEV__) {
185// return `http://localhost:${process.env.WEBPACK_DEV_SERVER_PORT || '3001'}/dist/${pathname}`
186// } else {
187// const segs = pathname.split('/').filter(seg => seg !== '/')
188// const file = segs.pop()
189// const dir = segs.length ? `${segs.join('/')}/` : ''
190// return `/${dir}${
191// require('./filterTargetFile')(
192// require('./readFilesInPath')(`./${pathDist}/public/${dir}`),
193// file
194// )}`
195// }
196// }