@rws-framework/client 2.13.0 → 2.13.1
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.
- package/builder/vite/rws.vite.config.ts +8 -2
- package/bun.lockb +0 -0
- package/cfg/build_steps/vite/_loaders.ts +7 -5
- package/cfg/build_steps/vite/loaders/html.ts +7 -9
- package/cfg/build_steps/vite/loaders/loader.type.ts +26 -2
- package/cfg/build_steps/vite/loaders/scss.ts +26 -13
- package/cfg/build_steps/vite/loaders/ts.ts +310 -16
- package/cfg/build_steps/vite/rws_scss_plugin.ts +6 -9
- package/cfg/build_steps/vite/scss/_compiler.ts +48 -54
- package/cfg/build_steps/vite/scss/_fonts.ts +1 -1
- package/cfg/build_steps/vite/types.ts +1 -0
- package/package.json +9 -8
|
@@ -11,7 +11,8 @@ const __dirname = path.dirname(__filename);
|
|
|
11
11
|
|
|
12
12
|
export const _DEFAULT_CFG: RWSViteConfig = {
|
|
13
13
|
dev: true,
|
|
14
|
-
tsConfigPath: path.resolve(rwsPath.findPackageDir(process.cwd()), 'tsconfig.json')
|
|
14
|
+
tsConfigPath: path.resolve(rwsPath.findPackageDir(process.cwd()), 'tsconfig.json'),
|
|
15
|
+
cssOutputPath: path.resolve(rwsPath.findPackageDir(process.cwd()), 'public', 'css'),
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export function rwsViteBuilder(config: Partial<RWSViteConfig> = _DEFAULT_CFG, devDebug = false): UserConfig {
|
|
@@ -19,6 +20,10 @@ export function rwsViteBuilder(config: Partial<RWSViteConfig> = _DEFAULT_CFG, de
|
|
|
19
20
|
config.tsConfigPath = _DEFAULT_CFG.tsConfigPath;
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
if(!config.cssOutputPath){
|
|
24
|
+
config.cssOutputPath = _DEFAULT_CFG.cssOutputPath;
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
const theConfig: RWSViteConfig = {..._DEFAULT_CFG, ...config};
|
|
23
28
|
|
|
24
29
|
// Return a plain configuration object
|
|
@@ -28,7 +33,8 @@ export function rwsViteBuilder(config: Partial<RWSViteConfig> = _DEFAULT_CFG, de
|
|
|
28
33
|
packageDir: rwsPath.findPackageDir(process.cwd()),
|
|
29
34
|
nodeModulesPath: `${rwsPath.findRootWorkspacePath(process.cwd())}/node_modules`,
|
|
30
35
|
tsConfigPath: theConfig.tsConfigPath,
|
|
31
|
-
|
|
36
|
+
cssOutputPath: theConfig.cssOutputPath as string,
|
|
37
|
+
dev: config.dev as boolean
|
|
32
38
|
}),
|
|
33
39
|
build: {
|
|
34
40
|
minify: !config.dev,
|
package/bun.lockb
ADDED
|
Binary file
|
|
@@ -2,17 +2,19 @@ import path from 'path';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import JSON5 from 'json5';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
import { Plugin } from 'vite';
|
|
6
5
|
import { RWSScssPlugin } from './rws_scss_plugin';
|
|
7
6
|
import { scssLoader, tsLoader, htmlLoader } from './loaders';
|
|
7
|
+
import { HTMLLoaderParams, IRWSViteLoader, LoaderContent, SCSSLoaderParams, TSLoaderParams } from './loaders/loader.type';
|
|
8
|
+
import { PluginOption } from 'vite';
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
+
const scssPlugin = new RWSScssPlugin();
|
|
10
11
|
|
|
11
12
|
interface RWSLoaderOptions {
|
|
12
13
|
packageDir: string;
|
|
13
14
|
nodeModulesPath: string;
|
|
15
|
+
cssOutputPath: string;
|
|
14
16
|
tsConfigPath: string;
|
|
15
|
-
|
|
17
|
+
dev: boolean;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
interface ViewDecoratorData {
|
|
@@ -22,9 +24,9 @@ interface ViewDecoratorData {
|
|
|
22
24
|
decoratorArgs: any;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
export function getRWSVitePlugins({ packageDir, nodeModulesPath, tsConfigPath,
|
|
27
|
+
export function getRWSVitePlugins({ packageDir, nodeModulesPath, tsConfigPath, cssOutputPath, dev }: RWSLoaderOptions): PluginOption[] {
|
|
26
28
|
return [
|
|
27
|
-
|
|
29
|
+
tsLoader({dev, scssPlugin: scssPlugin}), scssLoader({dev, scssPlugin: scssPlugin, cssOutputPath}), htmlLoader({dev})
|
|
28
30
|
];
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { IRWSViteLoader } from "./loader.type";
|
|
1
|
+
import { HTMLLoaderParams, IRWSViteLoader } from "./loader.type";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const loader: IRWSViteLoader<HTMLLoaderParams> = async (params: HTMLLoaderParams) => ({
|
|
4
4
|
name: 'rws-html',
|
|
5
5
|
async transform(code: string, id: string) {
|
|
6
6
|
if (!id.endsWith('.html')) return null;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
code,
|
|
11
|
-
map: null
|
|
12
|
-
};
|
|
7
|
+
|
|
8
|
+
return null;
|
|
13
9
|
}
|
|
14
|
-
});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default loader;
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
import { PluginOption } from 'vite';
|
|
2
|
+
import { RWSScssPlugin } from '../rws_scss_plugin';
|
|
3
|
+
|
|
4
|
+
export interface LoaderParams {
|
|
5
|
+
dev: boolean
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface TSLoaderParams extends LoaderParams {
|
|
9
|
+
scssPlugin: RWSScssPlugin
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SCSSLoaderParams extends LoaderParams {
|
|
14
|
+
scssPlugin: RWSScssPlugin,
|
|
15
|
+
cssOutputPath: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface HTMLLoaderParams extends LoaderParams {
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type LoaderContent = {
|
|
2
23
|
name: string,
|
|
24
|
+
enforce?: string,
|
|
3
25
|
transform(code: string, id: string): Promise<{ code: string, map: any } | null>
|
|
4
|
-
}
|
|
26
|
+
} | null;
|
|
27
|
+
|
|
28
|
+
export type IRWSViteLoader<P extends LoaderParams = LoaderParams> = (params: P) => PluginOption;
|
|
@@ -1,20 +1,33 @@
|
|
|
1
|
-
import { IRWSViteLoader } from "./loader.type";
|
|
2
|
-
import { RWSScssPlugin } from '../rws_scss_plugin';
|
|
1
|
+
import { IRWSViteLoader, SCSSLoaderParams } from "./loader.type";
|
|
3
2
|
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const loader: IRWSViteLoader<SCSSLoaderParams> = async (params: SCSSLoaderParams) => ({
|
|
6
6
|
name: 'rws-scss',
|
|
7
|
+
enforce: 'pre',
|
|
7
8
|
async transform(code: string, id: string) {
|
|
8
|
-
if (!id.endsWith('.scss')) return null;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
code,
|
|
12
|
-
path.dirname(id) + '/styles',
|
|
13
|
-
);
|
|
10
|
+
if (!id.endsWith('.scss')) return null;
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
if(code.indexOf('@save') > -1){
|
|
13
|
+
const result = await params.scssPlugin.compileScssCode(
|
|
14
|
+
code,
|
|
15
|
+
path.dirname(id),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const fileName: string = id.split('/').pop() as string;
|
|
19
|
+
const dirName: string = params.cssOutputPath ? params.cssOutputPath : path.dirname(id);
|
|
20
|
+
|
|
21
|
+
const fileNameArray = fileName.split('.');
|
|
22
|
+
|
|
23
|
+
const newFileName: string = path.join(dirName, fileNameArray.at(-2) + '.css')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
fs.writeFileSync(newFileName, result.code);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { code: '' };
|
|
19
30
|
}
|
|
20
|
-
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export default loader;
|
|
@@ -1,19 +1,313 @@
|
|
|
1
|
-
import { IRWSViteLoader } from "./loader.type";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { IRWSViteLoader, TSLoaderParams } from "./loader.type";
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import md5 from 'md5';
|
|
7
|
+
import JSON5 from 'json5'
|
|
8
|
+
import { RWSScssPlugin } from "../rws_scss_plugin";
|
|
9
|
+
|
|
10
|
+
interface DecoratorArgsData {
|
|
11
|
+
template?: string;
|
|
12
|
+
styles?: string;
|
|
13
|
+
ignorePackaging?: boolean;
|
|
14
|
+
debugPackaging?: boolean;
|
|
15
|
+
fastElementOptions?: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ViewDecoratorData {
|
|
19
|
+
decoratorArgs?: DecoratorArgsData;
|
|
20
|
+
tagName: string;
|
|
21
|
+
className: string;
|
|
22
|
+
classNamePrefix?: string | null; // Added this field
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface DecoratorExtract {
|
|
26
|
+
viewDecoratorData?: ViewDecoratorData | null;
|
|
27
|
+
replacedDecorator: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Cache manager - możesz to wydzielić do osobnego pliku
|
|
31
|
+
class CacheManager {
|
|
32
|
+
private cache: Map<string, string> = new Map();
|
|
33
|
+
private customOptions: any;
|
|
34
|
+
|
|
35
|
+
constructor(customOptions: any = null) {
|
|
36
|
+
this.customOptions = customOptions;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getCachedItem(filePath: string, hash: string): string | null {
|
|
40
|
+
const key = `${filePath}:${hash}`;
|
|
41
|
+
return this.cache.get(key) || null;
|
|
42
|
+
}
|
|
13
43
|
|
|
44
|
+
cacheItem(filePath: string, content: string, originalContent: string): void {
|
|
45
|
+
const key = `${filePath}:${md5(originalContent)}`;
|
|
46
|
+
this.cache.set(key, content);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Helper functions - też możesz wydzielić
|
|
51
|
+
class LoadersHelper {
|
|
52
|
+
static extractRWSViewArgs(content: string, noReplace = false): DecoratorExtract | null {
|
|
53
|
+
const viewReg = /@RWSView\(\s*["']([^"']+)["'](?:\s*,\s*([\s\S]*?))?\s*\)\s*(.*?\s+)?class\s+([a-zA-Z0-9_-]+)\s+extends\s+RWSViewComponent/gm;
|
|
54
|
+
|
|
55
|
+
let m: RegExpExecArray | null = null;;
|
|
56
|
+
let tagName: string | null = null;
|
|
57
|
+
let className: string | null = null;
|
|
58
|
+
let classNamePrefix: string | null = null;
|
|
59
|
+
let decoratorArgs: DecoratorArgsData | null = null;
|
|
60
|
+
|
|
61
|
+
const _defaultRWSLoaderOptions = {
|
|
62
|
+
templatePath: 'template.html',
|
|
63
|
+
stylesPath: 'styles.scss',
|
|
64
|
+
fastOptions: { shadowOptions: { mode: 'open' } }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
while ((m = viewReg.exec(content)) !== null) {
|
|
68
|
+
if (m.index === viewReg.lastIndex) {
|
|
69
|
+
viewReg.lastIndex++;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
m.forEach((match, groupIndex) => {
|
|
73
|
+
if (groupIndex === 1) {
|
|
74
|
+
tagName = match;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (groupIndex === 2) {
|
|
78
|
+
if (match) {
|
|
79
|
+
try {
|
|
80
|
+
decoratorArgs = JSON5.parse(match);
|
|
81
|
+
} catch(e){
|
|
82
|
+
console.log(chalk.red('Decorator options parse error: ') + e.message + '\n Problematic line:');
|
|
83
|
+
console.log(`
|
|
84
|
+
@RWSView(${tagName}, ${match})
|
|
85
|
+
`);
|
|
86
|
+
console.log(chalk.yellowBright(`Decorator options failed to parse for "${tagName}" component.`) + ' { decoratorArgs } defaulting to null.');
|
|
87
|
+
console.log(match);
|
|
88
|
+
|
|
89
|
+
throw new Error('Failed parsing @RWSView')
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (groupIndex === 3) {
|
|
95
|
+
if(match){
|
|
96
|
+
classNamePrefix = match;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (groupIndex === 4) {
|
|
101
|
+
className = match;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if(!tagName || !className){
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let processedContent = content;
|
|
111
|
+
|
|
112
|
+
let fastOptions = _defaultRWSLoaderOptions.fastOptions;
|
|
113
|
+
decoratorArgs = decoratorArgs as unknown as DecoratorArgsData;
|
|
114
|
+
if (decoratorArgs?.fastElementOptions) {
|
|
115
|
+
fastOptions = decoratorArgs.fastElementOptions;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let replacedDecorator: string | null = null;
|
|
119
|
+
|
|
120
|
+
if(!noReplace){
|
|
121
|
+
const [addedParamDefs, addedParams] = this._extractRWSViewDefs(fastOptions, decoratorArgs || {});
|
|
122
|
+
const replacedViewDecoratorContent = processedContent.replace(
|
|
123
|
+
viewReg,
|
|
124
|
+
`@RWSView('$1', null, { template: rwsTemplate, styles${addedParams.length ? ', options: {' + (addedParams.join(', ')) + '}' : ''} })\n$3class $4 extends RWSViewComponent `
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
replacedDecorator = `${addedParamDefs.join('\n')}\n${replacedViewDecoratorContent}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
14
130
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
131
|
+
viewDecoratorData: {
|
|
132
|
+
tagName,
|
|
133
|
+
className,
|
|
134
|
+
classNamePrefix,
|
|
135
|
+
decoratorArgs
|
|
136
|
+
},
|
|
137
|
+
replacedDecorator: replacedDecorator || '' // Ensure it's never null
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private static _extractRWSViewDefs(fastOptions = {}, decoratorArgs = {})
|
|
142
|
+
{
|
|
143
|
+
const addedParamDefs: string[] = [];
|
|
144
|
+
const addedParams: string[] = [];
|
|
145
|
+
|
|
146
|
+
for (const key in fastOptions){
|
|
147
|
+
addedParamDefs.push(`const ${key} = ${JSON.stringify(fastOptions[key])};`);
|
|
148
|
+
addedParams.push(key);
|
|
18
149
|
}
|
|
19
|
-
|
|
150
|
+
|
|
151
|
+
return [addedParamDefs, addedParams];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static async getStyles(plugin: RWSScssPlugin, filePath: string, addDependency: (path: string) => void, templateExists: boolean, stylesPath?: string, isDev?: boolean): Promise<string> {
|
|
155
|
+
if(!stylesPath){
|
|
156
|
+
stylesPath = 'styles/layout.scss';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let styles = 'const styles: null = null;'
|
|
160
|
+
const stylesFilePath = path.dirname(filePath) + '/' + stylesPath;
|
|
161
|
+
|
|
162
|
+
if (fs.existsSync(stylesFilePath)) {
|
|
163
|
+
const scsscontent = fs.readFileSync(stylesFilePath, 'utf-8');
|
|
164
|
+
|
|
165
|
+
const codeData = await plugin.compileScssCode(scsscontent, path.dirname(filePath) + '/styles');
|
|
166
|
+
const cssCode = codeData.code;
|
|
167
|
+
|
|
168
|
+
styles = isDev ? `import './${stylesPath}';\n` : '';
|
|
169
|
+
|
|
170
|
+
if (!templateExists) {
|
|
171
|
+
styles += `import { css } from '@microsoft/fast-element';\n`;
|
|
172
|
+
}
|
|
173
|
+
styles += `const styles = ${templateExists ? 'T.' : ''}css\`${cssCode}\`;\n`;
|
|
174
|
+
|
|
175
|
+
addDependency(path.dirname(filePath) + '/' + stylesPath);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return styles;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static async getTemplate(filePath: string, addDependency: (path: string) => void, templateName?: string, isDev?: boolean) {
|
|
182
|
+
if(!templateName){
|
|
183
|
+
templateName = 'template';
|
|
184
|
+
}
|
|
185
|
+
const templatePath = path.dirname(filePath) + `/${templateName}.html`;
|
|
186
|
+
let htmlFastImports: string | null = null;
|
|
187
|
+
const templateExists = fs.existsSync(templatePath);
|
|
188
|
+
let template = 'const rwsTemplate: null = null;';
|
|
189
|
+
|
|
190
|
+
if (templateExists) {
|
|
191
|
+
const templateContent = fs.readFileSync(templatePath, 'utf-8').replace(/<!--[\s\S]*?-->/g, '');
|
|
192
|
+
htmlFastImports = `import * as T from '@microsoft/fast-element';\nimport './${templateName}.html';\n`;
|
|
193
|
+
template = `
|
|
194
|
+
//@ts-ignore
|
|
195
|
+
let rwsTemplate: any = T.html\`${templateContent}\`;
|
|
196
|
+
`;
|
|
197
|
+
addDependency(templatePath);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return [template, htmlFastImports, templateExists];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Główny loader
|
|
205
|
+
const loader: IRWSViteLoader<TSLoaderParams> = async (params: TSLoaderParams) => {
|
|
206
|
+
|
|
207
|
+
const cacheManager = new CacheManager();
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
name: 'rws-typescript',
|
|
211
|
+
enforce: 'pre',
|
|
212
|
+
async transform(code: string, id: string) {
|
|
213
|
+
|
|
214
|
+
if (!id.endsWith('.ts')) return null;
|
|
215
|
+
if (id.endsWith('.debug.ts') || id.endsWith('.d.ts')) return null;
|
|
216
|
+
if (id.includes('node_modules') && !id.includes('@rws-framework')) return null;
|
|
217
|
+
|
|
218
|
+
let processedContent: string = code;
|
|
219
|
+
const isDev: boolean = params.dev;
|
|
220
|
+
let isIgnored: boolean = false;
|
|
221
|
+
let isDebugged: boolean = false;
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const decoratorExtract: DecoratorExtract | null = await LoadersHelper.extractRWSViewArgs(processedContent);
|
|
225
|
+
const decoratorData: ViewDecoratorData | null = decoratorExtract?.viewDecoratorData || null;
|
|
226
|
+
|
|
227
|
+
const cachedCode: string = processedContent;
|
|
228
|
+
// const cachedTS = cacheManager.getCachedItem(id, md5(cachedCode as string));
|
|
229
|
+
|
|
230
|
+
// if (cachedTS) {
|
|
231
|
+
// return {
|
|
232
|
+
// code: cachedTS,
|
|
233
|
+
// map: null
|
|
234
|
+
// };
|
|
235
|
+
// }
|
|
236
|
+
|
|
237
|
+
if (!decoratorData) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
let templateName: string | null = decoratorData.decoratorArgs?.template || null;
|
|
242
|
+
let stylesPath = decoratorData.decoratorArgs?.styles || null;
|
|
243
|
+
isIgnored = decoratorData.decoratorArgs?.ignorePackaging || false;
|
|
244
|
+
isDebugged = decoratorData.decoratorArgs?.debugPackaging || false;
|
|
245
|
+
|
|
246
|
+
const tagName = decoratorData.tagName;
|
|
247
|
+
const className = decoratorData.className;
|
|
248
|
+
|
|
249
|
+
const defaultTemplatePath = path.resolve(path.dirname(id), 'template.html');
|
|
250
|
+
const defaultStylesPath = path.resolve(path.dirname(id), 'styles', 'layout.scss');
|
|
251
|
+
|
|
252
|
+
if(!templateName && fs.existsSync(defaultTemplatePath)){
|
|
253
|
+
templateName ='template';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if(!stylesPath && fs.existsSync(defaultStylesPath)){
|
|
257
|
+
stylesPath ='styles/layout.scss';
|
|
258
|
+
}
|
|
259
|
+
console.log({stylesPath, templateName, tagName})
|
|
260
|
+
|
|
261
|
+
if (tagName && templateName && stylesPath) {
|
|
262
|
+
const [template, htmlFastImports, templateExists] = await LoadersHelper.getTemplate(
|
|
263
|
+
id,
|
|
264
|
+
(path) => this.addWatchFile(path),
|
|
265
|
+
templateName,
|
|
266
|
+
isDev
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const styles = await LoadersHelper.getStyles(
|
|
270
|
+
params.scssPlugin,
|
|
271
|
+
id,
|
|
272
|
+
(path) => this.addWatchFile(path),
|
|
273
|
+
templateExists as boolean,
|
|
274
|
+
stylesPath,
|
|
275
|
+
isDev
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
console.log({styles})
|
|
279
|
+
|
|
280
|
+
if (className && decoratorExtract?.replacedDecorator) {
|
|
281
|
+
processedContent = `${template}\n${styles}\n${decoratorExtract.replacedDecorator}`;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
processedContent = `${htmlFastImports ? htmlFastImports + '\n' : ''}${processedContent}`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const debugTsPath = id.replace('.ts', '.debug.ts');
|
|
288
|
+
|
|
289
|
+
if (fs.existsSync(debugTsPath)) {
|
|
290
|
+
fs.unlinkSync(debugTsPath);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (isDebugged) {
|
|
294
|
+
console.log(chalk.red('[RWS BUILD] Debugging into: ' + debugTsPath));
|
|
295
|
+
fs.writeFileSync(debugTsPath, processedContent);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
cacheManager.cacheItem(id, processedContent, cachedCode);
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
code: processedContent,
|
|
302
|
+
map: null
|
|
303
|
+
};
|
|
304
|
+
} catch (e) {
|
|
305
|
+
console.log(chalk.red('RWS Typescript loader error:'));
|
|
306
|
+
console.error(e);
|
|
307
|
+
throw new Error('RWS Build failed on: ' + id);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export default loader;
|
|
@@ -39,21 +39,18 @@ class RWSScssPlugin {
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
async compileFile(scssPath): Promise<{ code: string, dependencies: string[]}>
|
|
42
|
+
async compileFile(scssPath): Promise<{ code: string, dependencies: string[]}>
|
|
43
43
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
let scssCode = this._scss_fs.getCodeFromFile(scssPath);
|
|
48
|
-
|
|
49
|
-
return await this._scss_compiler.compileScssCode(scssCode, path.dirname(scssPath), null, scssPath);
|
|
44
|
+
scssPath = this._scss_import.processImportPath(scssPath, path.dirname(scssPath))
|
|
45
|
+
let scssCode = this._scss_fs.getCodeFromFile(scssPath);
|
|
46
|
+
return await this._scss_compiler.compileScssCode(scssCode, path.dirname(scssPath), null, scssPath);
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
async compileScssCode(scssCode: string, scssPath: string): Promise<{ code: string, dependencies: string[]}>
|
|
53
50
|
{
|
|
54
|
-
|
|
51
|
+
return await this._scss_compiler.compileScssCode(scssCode, scssPath, null, scssPath);
|
|
55
52
|
}
|
|
56
|
-
|
|
53
|
+
|
|
57
54
|
writeCssFile(scssFilePath: string, cssContent: string): string
|
|
58
55
|
{
|
|
59
56
|
return this._scss_fs.writeCssFile(scssFilePath, cssContent);
|
|
@@ -1,101 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import sass from 'sass-embedded';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import emojiRegex from 'emoji-regex';
|
|
5
5
|
|
|
6
6
|
import _scss_fonts_builder from './_fonts';
|
|
7
7
|
let _scss_fonts: any = null;
|
|
8
|
-
|
|
9
8
|
import _scss_import_builder from './_import';
|
|
10
9
|
let _scss_import: any = null;
|
|
11
10
|
|
|
12
|
-
function compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false): {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
{
|
|
11
|
+
async function compileScssCode(scssCode: string, fileRootDir: string, createFile:boolean = false, filePath: string | null = null, minify: boolean = false): Promise<{
|
|
12
|
+
code: string,
|
|
13
|
+
dependencies: string[]
|
|
14
|
+
}> {
|
|
17
15
|
_scss_fonts = _scss_fonts_builder(this);
|
|
18
16
|
_scss_import = _scss_import_builder(this);
|
|
19
17
|
|
|
20
18
|
const [scssImports] = _scss_import.extractScssImports(scssCode, fileRootDir);
|
|
21
|
-
|
|
22
19
|
const dependencies = scssImports.map((item) => item[2]);
|
|
23
20
|
|
|
24
21
|
if (scssImports && scssImports.length) {
|
|
25
|
-
|
|
22
|
+
scssCode = _scss_import.replaceImports(_scss_import.processImports(scssImports, fileRootDir), scssCode);
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
const uses = _scss_import.extractScssUses(scssCode)[0];
|
|
29
26
|
let scssUses = '';
|
|
30
|
-
|
|
31
|
-
|
|
32
27
|
uses.forEach(scssUse => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
const useLine = scssUse[1];
|
|
29
|
+
if(scssCode.indexOf(useLine) === -1){
|
|
30
|
+
scssUses += useLine + '\n';
|
|
31
|
+
scssCode = scssCode.replace(useLine + '\n', '');
|
|
32
|
+
}
|
|
38
33
|
});
|
|
39
34
|
|
|
40
35
|
scssCode = removeComments(scssUses + scssCode);
|
|
41
36
|
|
|
42
|
-
try {
|
|
43
|
-
const result = sass.compileString(scssCode, { loadPaths: [fileRootDir]});
|
|
37
|
+
try {
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
console.error('SASS Error in', fileRootDir);
|
|
39
|
+
const result: sass.CompileResult = await sass.compileStringAsync(scssCode, {
|
|
40
|
+
loadPaths: [fileRootDir],
|
|
41
|
+
style: minify ? "compressed" : "expanded",
|
|
42
|
+
sourceMap: false
|
|
43
|
+
});
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
throw err;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
45
|
+
let compiledCode = result.css.toString();
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
compiledCode = _scss_fonts.replaceFontUrlWithBase64(compiledCode);
|
|
48
|
+
compiledCode = replaceEmojisWithQuestionMark(compiledCode, fileRootDir);
|
|
49
|
+
return { code: compiledCode, dependencies };
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.error('SASS Error in', fileRootDir);
|
|
52
|
+
console.error(err);
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
59
56
|
|
|
57
|
+
function checkForImporterType(_module, checkTypeExt) {
|
|
58
|
+
let importingFileExtension = '';
|
|
60
59
|
if (_module && _module.issuer && _module.issuer.resource) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
importingFileExtension = path.extname(_module.issuer.resource);
|
|
61
|
+
if (importingFileExtension === ('.' + checkTypeExt)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
65
64
|
} else {
|
|
66
|
-
|
|
65
|
+
return false;
|
|
67
66
|
}
|
|
68
|
-
|
|
69
67
|
return false
|
|
70
|
-
|
|
68
|
+
}
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
function replaceEmojisWithQuestionMark(code, componentDir) {
|
|
73
71
|
const regex = emojiRegex();
|
|
74
72
|
let hasEmoji = false;
|
|
75
|
-
|
|
76
73
|
const result = code.replace(regex, (match) => {
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
hasEmoji = true;
|
|
75
|
+
return '?';
|
|
79
76
|
});
|
|
80
|
-
|
|
81
77
|
if (hasEmoji) {
|
|
82
|
-
|
|
78
|
+
console.log(chalk.yellow(`Emojis in css detected and replaced with "?" in "${path.dirname(componentDir)}" component`));
|
|
83
79
|
}
|
|
84
|
-
|
|
85
80
|
return result;
|
|
86
|
-
|
|
81
|
+
}
|
|
87
82
|
|
|
88
|
-
|
|
83
|
+
function removeComments(code) {
|
|
89
84
|
code = code.replace(/\/\/.*$/gm, '');
|
|
90
85
|
code = code.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
91
86
|
code = code.replace(/^\s*$(?:\r\n?|\n)/gm, '');
|
|
92
|
-
|
|
93
87
|
return code;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default function(element) {
|
|
97
91
|
return {
|
|
98
92
|
checkForImporterType: checkForImporterType.bind(element),
|
|
99
93
|
compileScssCode: compileScssCode.bind(element)
|
|
100
94
|
};
|
|
101
|
-
|
|
95
|
+
};
|
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const FONT_REGEX = /url\(['"]?(.+?\.(woff|woff2|eot|ttf|otf))['"]?\)/gm;
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import _scss_import_builder from './_import';
|
|
6
6
|
let _scss_import: any = null;
|
|
7
7
|
|
|
8
8
|
function hasFontEmbeds(css) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rws-framework/client",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.13.
|
|
4
|
+
"version": "2.13.1",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"docs": "typedoc --tsconfig ./tsconfig.json"
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"he": "^1.2.0",
|
|
36
36
|
"json5": "^2.2.3",
|
|
37
37
|
"lodash": "^4.17.21",
|
|
38
|
-
"moment": "^2.29.4",
|
|
38
|
+
"moment": "^2.29.4",
|
|
39
39
|
"partial-json-parser": "^1.0.0",
|
|
40
40
|
"reflect-metadata": "^0.1.13",
|
|
41
41
|
"resolve-url-loader": "^5.0.0",
|
|
42
|
-
"sanitize-html": "^2.12.1",
|
|
42
|
+
"sanitize-html": "^2.12.1",
|
|
43
43
|
"socket.io-client": "^4.7.2",
|
|
44
44
|
"upload": "^1.3.2",
|
|
45
45
|
"url-router": "^13.0.0",
|
|
@@ -54,25 +54,26 @@
|
|
|
54
54
|
"@types/he": "^1.2.3",
|
|
55
55
|
"@types/sanitize-html": "^2.11.0",
|
|
56
56
|
"@types/uuid": "^9.0.7",
|
|
57
|
-
"@typescript-eslint/parser": "^5.0.0",
|
|
57
|
+
"@typescript-eslint/parser": "^5.0.0",
|
|
58
58
|
"browser-sync": "^2.29.3",
|
|
59
59
|
"clean-webpack-plugin": "^4.0.0",
|
|
60
60
|
"css-loader": "^6.8.1",
|
|
61
61
|
"css-minimizer-webpack-plugin": "^5.0.1",
|
|
62
62
|
"eslint": "^6.0.0",
|
|
63
|
-
"file-loader": "^6.2.0",
|
|
63
|
+
"file-loader": "^6.2.0",
|
|
64
64
|
"html-webpack-plugin": "^5.5.3",
|
|
65
65
|
"loader-utils": "^3.2.1",
|
|
66
66
|
"mini-css-extract-plugin": "^2.7.6",
|
|
67
67
|
"minimatch": "^9.0.4",
|
|
68
68
|
"node-sass": "^9.0.0",
|
|
69
|
-
"raw-loader": "^4.0.2",
|
|
70
|
-
"source-map": "^0.7.4",
|
|
69
|
+
"raw-loader": "^4.0.2",
|
|
70
|
+
"source-map": "^0.7.4",
|
|
71
71
|
"source-map-support": "^0.5.21",
|
|
72
|
-
"stacktrace-gps": "^3.1.2",
|
|
72
|
+
"stacktrace-gps": "^3.1.2",
|
|
73
73
|
"sass": "1.69.7",
|
|
74
74
|
"sass-loader": "^13.3.2",
|
|
75
75
|
"scss-loading-animations": "^1.0.1",
|
|
76
|
+
"sass-embedded": "^1.83.4",
|
|
76
77
|
"speed-measure-webpack-plugin": "^1.5.0",
|
|
77
78
|
"style-loader": "^3.3.3",
|
|
78
79
|
"terser-webpack-plugin": "^5.3.9",
|