@rws-framework/client 2.14.0 → 2.15.0

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.
@@ -32,6 +32,7 @@ module.exports = async (copyList = {}, pluginCfg) => {
32
32
  // If sourcePath is a directory, collect all files recursively
33
33
  const allFiles = collectFiles(sourcePath);
34
34
  allFiles.forEach((file) => {
35
+
35
36
  const relativePath = path.relative(sourcePath, file);
36
37
  const targetFilePath = path.join(targetPath, relativePath);
37
38
  const targetFileDir = path.dirname(targetFilePath);
@@ -8,7 +8,9 @@ module.exports = async function(content) {
8
8
  const componentPath = path.resolve(componentDir, 'component.ts');
9
9
  const isDev = this._compiler.options.mode === 'development';
10
10
  const saveFile = content.indexOf('@save') > -1;
11
- const plugin = new RWSScssPlugin();
11
+ const plugin = new RWSScssPlugin({
12
+ rwsWorkspaceDir: this.query?.rwsWorkspaceDir
13
+ });
12
14
  let fromTs = false;
13
15
 
14
16
  if(saveFile){
@@ -12,8 +12,7 @@ module.exports = async function(content) {
12
12
  const filePath = this.resourcePath;
13
13
  const isDev = this._compiler.options.mode === 'development';
14
14
  let isIgnored = false;
15
- let isDebugged = false;
16
-
15
+ let isDebugged = false;
17
16
  // timingStart('decorator_extraction');
18
17
  const decoratorExtract = LoadersHelper.extractRWSViewArgs(processedContent);
19
18
  const decoratorData = decoratorExtract ? decoratorExtract.viewDecoratorData : null;
@@ -62,7 +61,7 @@ module.exports = async function(content) {
62
61
  try {
63
62
  if(tagName){
64
63
  const [template, htmlFastImports, templateExists] = await LoadersHelper.getTemplate(filePath, this.addDependency, templateName, isDev);
65
- const styles = await LoadersHelper.getStyles(filePath, this.addDependency, templateExists, stylesPath, isDev);
64
+ const styles = await LoadersHelper.getStyles(filePath, this.query?.rwsWorkspaceDir, this.addDependency, templateExists, stylesPath, isDev);
66
65
 
67
66
  if(className){
68
67
  const replacedViewDecoratorContent = decoratorExtract.replacedDecorator;
@@ -22,7 +22,7 @@ const _MAIN_PACKAGE = rwsPath.findRootWorkspacePath(process.cwd());
22
22
 
23
23
  // #SECTION INIT OPTIONS
24
24
 
25
- const RWSWebpackWrapper = async (rwsFrontendConfig) => {
25
+ const RWSWebpackWrapper = async (rwsFrontendConfig, _packageDir) => {
26
26
  const {
27
27
  executionDir,
28
28
  isWatcher,
@@ -42,11 +42,10 @@ const RWSWebpackWrapper = async (rwsFrontendConfig) => {
42
42
  devTools,
43
43
  devDebug,
44
44
  devRouteProxy,
45
- tsConfigPath,
45
+ tsConfig,
46
46
  rwsPlugins,
47
- _packageDir,
48
47
  BuildConfigurator
49
- } = await getBuildConfig(rwsFrontendConfig);
48
+ } = await getBuildConfig(rwsFrontendConfig, _packageDir);
50
49
 
51
50
  timeLog({ devDebug });
52
51
 
@@ -55,25 +54,20 @@ const RWSWebpackWrapper = async (rwsFrontendConfig) => {
55
54
  }
56
55
 
57
56
  rwsPath.removeDirectory(outputDir, true);
58
- buildInfo.start(executionDir, tsConfigPath, outputDir, isDev, publicDir, isParted, partedPrefix, partedDirUrlPrefix, devTools, rwsFrontendConfig.rwsPlugins);
57
+ buildInfo.start(executionDir, tsConfig, outputDir, isDev, publicDir, isParted, partedPrefix, partedDirUrlPrefix, devTools, rwsFrontendConfig.rwsPlugins);
59
58
 
60
59
  // #SECTION INIT PLUGINS && ENV VARS DEFINES
61
- addStartPlugins(rwsFrontendConfig, BuildConfigurator, devDebug, isHotReload, isReport, tsConfigPath);
60
+ addStartPlugins(rwsFrontendConfig, BuildConfigurator, devDebug, isHotReload, isReport);
62
61
 
63
62
  const WEBPACK_AFTER_ACTIONS = rwsFrontendConfig.actions || [];
64
63
  const WEBPACK_AFTER_ERROR_ACTIONS = rwsFrontendConfig.error_actions || [];
65
64
 
66
- const modules_setup = ['node_modules'];
65
+ const modules_setup = [path.resolve(tools.findRootWorkspacePath(executionDir), 'node_modules')];
67
66
 
68
67
  let optimConfig = null;
69
68
  let aliases = rwsFrontendConfig.aliases || {};
70
69
 
71
- console.log({
72
- __filename,
73
- _packageDir
74
- });
75
-
76
- aliases = { ...aliases, ...loadAliases(__dirname, path.resolve(_MAIN_PACKAGE, 'node_modules'), executionDir) }
70
+ aliases = { ...aliases, ...loadAliases(_packageDir, path.resolve(_MAIN_PACKAGE, 'node_modules'), executionDir) }
77
71
 
78
72
  // #SECTION PLUGIN STARTING HOOKS
79
73
 
@@ -85,22 +79,15 @@ const RWSWebpackWrapper = async (rwsFrontendConfig) => {
85
79
 
86
80
 
87
81
  // #SECTION RWS COMPONENT SCAN && PARTED PROCESSING
88
- const RWSComponents = scanComponents(await partedComponentsEvents(partedComponentsLocations, rwsPlugins, isParted), executionDir, __dirname);
82
+ const RWSComponents = scanComponents(await partedComponentsEvents(partedComponentsLocations, rwsPlugins, isParted), executionDir, _packageDir);
89
83
  console.log(`${chalk.cyanBright('RWS Scanned')} ${chalk.yellowBright(RWSComponents.length)} components`);
90
- const { automatedChunks, automatedEntries } = setComponentsChunks(rwsFrontendConfig.entry, RWSComponents, isParted);
84
+ const { automatedChunks, automatedEntries } = setComponentsChunks(rwsFrontendConfig.entrypoint, RWSComponents, isParted);
91
85
 
92
86
  // #SECTION RWS INFO FILE
93
87
  generateRWSInfoFile(outputDir, automatedEntries);
94
88
  console.log(chalk.greenBright(`RWSInfo file generated.`));
95
89
 
96
90
 
97
- // #SECTION TSCONFIG VALIDATION/SETUP
98
- const tsValidated = tools.setupTsConfig(tsConfigPath, executionDir, rwsFrontendConfig.aliases);
99
-
100
- if (!tsValidated) {
101
- throw new Error('RWS Webpack build failed.');
102
- }
103
-
104
91
  if (!isDev) {
105
92
  // #SECTION RWS PROD SETUP
106
93
 
@@ -128,7 +115,6 @@ const RWSWebpackWrapper = async (rwsFrontendConfig) => {
128
115
  // #SECTION RWS WEBPACK BUILD
129
116
  const cfgExport = createWebpackConfig(
130
117
  executionDir,
131
- path.resolve(__dirname, '..', '..'),
132
118
  _packageDir,
133
119
  isDev,
134
120
  devTools,
@@ -140,10 +126,11 @@ const RWSWebpackWrapper = async (rwsFrontendConfig) => {
140
126
  automatedChunks,
141
127
  modules_setup,
142
128
  aliases,
143
- tsConfigPath,
129
+ tsConfig,
144
130
  RWS_WEBPACK_PLUGINS_BAG.getPlugins(),
145
131
  rwsExternals,
146
- devExternalsVars
132
+ devExternalsVars,
133
+ rwsFrontendConfig.entrypoint
147
134
  );
148
135
 
149
136
  if (optimConfig) {
@@ -13,17 +13,23 @@ let _scss_fs = null;
13
13
 
14
14
  class RWSScssPlugin {
15
15
  autoCompile = [];
16
+ rwsWorkspaceDir = null;
16
17
 
17
- constructor(params) {
18
- this.node_modules_dir = (fileDir) => path.relative(fileDir, _tools.findRootWorkspacePath(process.cwd())) + '/node_modules/'
18
+ constructor(params = {
19
+ rwsWorkspaceDir: null,
20
+ autoCompile: []
21
+ }) {
22
+ this.node_modules_dir = (fileDir) => path.relative(fileDir, _tools.findRootWorkspacePath(process.cwd() + '/node_modules'))
19
23
  _scss_import = _scss_import_builder(this);
20
24
  _scss_fs = _scss_fs_builder(this);
21
25
  _scss_compiler = _scss_compiler_builder(this);
22
26
 
23
- if (!params) {
24
- params = {};
27
+ if(!params.rwsWorkspaceDir){
28
+ throw new Error('Pass "rwsWorkspaceDir" to the "@rws-framework/client/builder/webpack/loaders/rws_fast_ts_loader.js" loader.');
25
29
  }
26
30
 
31
+ this.rwsWorkspaceDir = params.rwsWorkspaceDir;
32
+
27
33
  if (!!params.autoCompile && params.autoCompile.length > 0) {
28
34
  this.autoCompile = params.autoCompile;
29
35
  }
@@ -33,7 +39,6 @@ class RWSScssPlugin {
33
39
  this.compileFile(sassFile, true);
34
40
  }
35
41
  }
36
-
37
42
 
38
43
  apply(compiler) {
39
44
  const _self = this;
@@ -42,21 +47,25 @@ class RWSScssPlugin {
42
47
  }
43
48
 
44
49
  async compileFile(scssPath) {
45
- scssPath = _scss_import.processImportPath(scssPath, path.dirname(scssPath))
50
+ scssPath = _scss_import.processImportPath(scssPath, this.rwsWorkspaceDir, path.dirname(scssPath))
46
51
 
47
52
 
48
- let scssCode = _scss_fs.getCodeFromFile(scssPath);
53
+ let scssCode = _scss_fs.getCodeFromFile(scssPath, this.rwsWorkspaceDir);
49
54
 
50
- return await _scss_compiler.compileScssCode(scssCode, path.dirname(scssPath), null, scssPath);
55
+ return await _scss_compiler.compileScssCode(scssCode, path.dirname(scssPath), this.rwsWorkspaceDir);
51
56
  }
52
57
 
53
58
  async compileScssCode(scssCode, scssPath){
54
- return await _scss_compiler.compileScssCode(scssCode, scssPath, null, scssPath);
59
+ return await _scss_compiler.compileScssCode(scssCode, scssPath, this.rwsWorkspaceDir);
55
60
  }
56
61
 
57
62
  writeCssFile(scssFilePath, cssContent){
58
63
  return _scss_fs.writeCssFile(scssFilePath, cssContent);
59
64
  }
65
+
66
+ getRWSWorkspaceDir() {
67
+ return this.rwsWorkspaceDir;
68
+ }
60
69
  }
61
70
 
62
71
  module.exports = RWSScssPlugin;
@@ -9,16 +9,15 @@ let _scss_fonts = null;
9
9
  const _scss_import_builder = require('./_import');
10
10
  let _scss_import = null;
11
11
 
12
- function compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false) {
12
+ function compileScssCode(scssCode, fileRootDir, rwsWorkspaceDir) {
13
13
  _scss_fonts = _scss_fonts_builder(this);
14
- _scss_import = _scss_import_builder(this);
15
-
16
- const [scssImports] = _scss_import.extractScssImports(scssCode, fileRootDir);
14
+ _scss_import = _scss_import_builder(this);
15
+ const [scssImports] = _scss_import.extractScssImports(scssCode, rwsWorkspaceDir, fileRootDir);
17
16
 
18
17
  const dependencies = scssImports.map((item) => item[2]);
19
18
 
20
19
  if (scssImports && scssImports.length) {
21
- scssCode = _scss_import.replaceImports(_scss_import.processImports(scssImports, fileRootDir), scssCode);
20
+ scssCode = _scss_import.replaceImports(_scss_import.processImports(scssImports, rwsWorkspaceDir, fileRootDir), scssCode);
22
21
  }
23
22
 
24
23
  const uses = _scss_import.extractScssUses(scssCode)[0];
@@ -39,7 +38,7 @@ function compileScssCode(scssCode, fileRootDir, createFile = false, filePath = n
39
38
  const result = sass.compileString(scssCode, { loadPaths: [fileRootDir]});
40
39
 
41
40
  let compiledCode = result.css.toString();
42
- compiledCode = _scss_fonts.replaceFontUrlWithBase64(compiledCode);
41
+ compiledCode = _scss_fonts.replaceFontUrlWithBase64(compiledCode, rwsWorkspaceDir);
43
42
  compiledCode = replaceEmojisWithQuestionMark(compiledCode, fileRootDir);
44
43
  return { code: compiledCode, dependencies};
45
44
  } catch (err) {
@@ -44,7 +44,7 @@ function convertFontToBase64(fontPath) {
44
44
  return fs.readFileSync(fontPath, { encoding: 'base64' });
45
45
  }
46
46
 
47
- function replaceFontUrlWithBase64(cssContent) {
47
+ function replaceFontUrlWithBase64(cssContent, rwsWorkspaceDir) {
48
48
  const fontFaceRegex = /@font-face\s*\{[^}]*\}/g;
49
49
  let fontFaces = [...cssContent.matchAll(fontFaceRegex)];
50
50
  _scss_import = _scss_import_builder(this);
@@ -58,7 +58,7 @@ function replaceFontUrlWithBase64(cssContent) {
58
58
 
59
59
  while ((match = urlRegex.exec(fontFaceContent)) !== null) {
60
60
  // Create a promise to convert each font to Base64 and replace in CSS
61
- const base64 = convertFontToBase64(_scss_import.processImportPath(match[2], null, true));
61
+ const base64 = convertFontToBase64(_scss_import.processImportPath(match[2], rwsWorkspaceDir, null, true));
62
62
  const base64Font = `data:font/woff2;base64,${base64}`;
63
63
 
64
64
  modifiedFontFaceContent = modifiedFontFaceContent.replace(match[2], base64Font);
@@ -47,13 +47,14 @@ function readSCSSFilesFromDirectory(dirPath) {
47
47
  };
48
48
 
49
49
 
50
- function getCodeFromFile(filePath) {
50
+ function getCodeFromFile(filePath, rwsWorkspaceDir) {
51
51
  filePath = filePath.replace('//', '/');
52
52
  const _scss_import_builder = require('./_import');
53
53
  _scss_import = _scss_import_builder(this);
54
54
 
55
55
  if (!fs.existsSync(filePath)) {
56
- const processedImportPath = _scss_import.processImportPath(filePath, path.dirname(filePath));
56
+ const processedImportPath = _scss_import.processImportPath(filePath, rwsWorkspaceDir, path.dirname(filePath));
57
+
57
58
  if (!fs.existsSync(processedImportPath)) {
58
59
  throw new Error(`SCSS loader: File path "${filePath}" was not found.`);
59
60
  }
@@ -1,5 +1,5 @@
1
1
  const { rwsPath } = require('@rws-framework/console');
2
-
2
+ const chalk = require('chalk');
3
3
  const _scss_fs_builder = require('./_fs');
4
4
  let _scss_fs = null;
5
5
  const fs = require('fs');
@@ -7,26 +7,34 @@ const path = require('path');
7
7
  const CSS_IMPORT_REGEX = /^(?!.*\/\/)(?!.*\/\*).*@import\s+['"]((?![^'"]*:[^'"]*).+?)['"];?/gm;
8
8
  const SCSS_USE_REGEX = /^(?!.*\/\/)(?!.*\/\*).*@use\s+['"]?([^'"\s]+)['"]?;?/gm;
9
9
 
10
- const WORKSPACE = rwsPath.findRootWorkspacePath(process.cwd());
10
+ const WORKSPACE_ROOT = rwsPath.findPackageDir(process.cwd());
11
11
 
12
- function processImportPath(importPath, fileRootDir = null, noext = false) {
12
+ function processImportPath(importPath, rwsWorkspaceDir, fileRootDir = null, noext = false) {
13
13
  _scss_fs = _scss_fs_builder(this);
14
-
14
+ const workspaceDir = this.getRWSWorkspaceDir ? this.getRWSWorkspaceDir() : rwsWorkspaceDir;
15
+
15
16
  if (importPath.split('')[0] === '~') {
16
17
  return fillSCSSExt(replaceWithNodeModules(importPath, null, true), noext);
17
18
  }
18
19
 
19
20
  if (importPath.indexOf('@rws-mixins') === 0) {
20
- return path.resolve(rwsPath.findPackageDir(__dirname), 'src', 'styles', 'includes.scss');
21
+ return path.resolve(rwsPath.findPackageDir(workspaceDir), 'src', 'styles', 'includes.scss');
21
22
  }
22
23
 
23
24
  if (importPath.indexOf('@cwd') === 0) {
24
- return fillSCSSExt(process.cwd() + '/' + importPath.slice(4), noext);
25
+ return fillSCSSExt(path.join(process.cwd(), importPath.slice(4)), noext);
25
26
  }
26
27
 
27
28
  if (importPath.split('')[0] === '/') {
29
+ const originalImport = fillSCSSExt(importPath, noext);
30
+
31
+ if(!fs.existsSync(originalImport)){
32
+ const absoluteImport = fillSCSSExt(path.join(workspaceDir, 'src', importPath), noext);
28
33
 
29
- return fillSCSSExt(importPath, noext);
34
+ return absoluteImport;
35
+ }
36
+
37
+ return originalImport;
30
38
  }
31
39
 
32
40
  if (fileRootDir) {
@@ -79,7 +87,30 @@ function fillSCSSExt(scssPath, noext = false) {
79
87
  return scssPath;
80
88
  }
81
89
 
82
- function extractScssImports(fileContent, importRootPath) {
90
+ function fillSCSSExt(scssPath, noext = false) {
91
+ const underscoredPath = underscorePath(scssPath, noext);
92
+ let ext = scssPath;
93
+
94
+ if (!fs.existsSync(scssPath) && fs.existsSync(underscoredPath)) {
95
+ ext = underscoredPath;
96
+ }
97
+
98
+ if (noext) {
99
+ ext = scssPath;
100
+ }
101
+
102
+ if ((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)) {
103
+ ext = `${scssPath}.scss`;
104
+ }
105
+
106
+ if (fs.existsSync(`_${scssPath}.scss`)) {
107
+ ext = `${scssPath}.scss`;
108
+ }
109
+
110
+ return ext;
111
+ }
112
+
113
+ function extractScssImports(fileContent, rwsWorkspaceDir, importRootPath) {
83
114
  _scss_fs = _scss_fs_builder(this);
84
115
  let match;
85
116
  const imports = [];
@@ -92,9 +123,9 @@ function extractScssImports(fileContent, importRootPath) {
92
123
  importRootPath = path.dirname(importRootPath);
93
124
  }
94
125
 
95
- const processedImportPath = processImportPath(importPath, importRootPath);
126
+ const processedImportPath = processImportPath(importPath, rwsWorkspaceDir, importRootPath);
96
127
 
97
- imports.push([processedImportPath, importLine, path.resolve(processedImportPath)]);
128
+ imports.push([processedImportPath, importLine, path.resolve(processedImportPath), rwsWorkspaceDir]);
98
129
  }
99
130
 
100
131
  return [imports, fileContent];
@@ -125,11 +156,12 @@ function detectImports(code) {
125
156
 
126
157
  function replaceWithNodeModules(input, fileDir = null, absolute = false, token = '~') {
127
158
  _scss_fs = _scss_fs_builder(this);
128
- return input.replace(token, absolute ? `${path.resolve(WORKSPACE, 'node_modules')}/` : this.node_modules_dir(fileDir ? fileDir : process.cwd()));
159
+ return input.replace(token, absolute ? `${path.resolve(WORKSPACE_ROOT, 'node_modules')}/` : this.node_modules_dir(fileDir ? fileDir : process.cwd()));
129
160
  }
130
161
 
131
- function processImports(imports, fileRootDir, importStorage = {}, sub = false) {
162
+ function processImports(imports, fileRootDir, rwsWorkspaceDir, importStorage = {}, sub = false) {
132
163
  _scss_fs = _scss_fs_builder(this);
164
+
133
165
  const importResults = [];
134
166
 
135
167
  const getStorage = (sourceComponentPath, importedFileContent) => {
@@ -143,18 +175,20 @@ function processImports(imports, fileRootDir, importStorage = {}, sub = false) {
143
175
 
144
176
  return '';
145
177
  }
146
-
178
+
179
+
147
180
  imports.forEach(importData => {
148
181
  const originalImportPath = importData[0];
149
- let importPath = processImportPath(originalImportPath, fileRootDir);
150
- _scss_fs = _scss_fs_builder(this);
151
- let replacedScssContent = getStorage(importPath, _scss_fs.getCodeFromFile(importPath).replace(/\/\*[\s\S]*?\*\//g, ''));
182
+ const workspaceDir = this.getRWSWorkspaceDir ? this.getRWSWorkspaceDir() : importData[3];
152
183
 
153
- const recursiveImports = extractScssImports(replacedScssContent, importPath)[0];
184
+ let importPath = processImportPath(originalImportPath, workspaceDir, fileRootDir);
154
185
 
155
- if (recursiveImports.length) {
186
+ let replacedScssContent = getStorage(importPath, _scss_fs.getCodeFromFile(importPath, workspaceDir).replace(/\/\*[\s\S]*?\*\//g, ''));
187
+
188
+ const recursiveImports = extractScssImports(replacedScssContent, workspaceDir, importPath)[0];
156
189
 
157
- replacedScssContent = replaceImports(processImports(recursiveImports, path.dirname(importPath), importStorage, true), replacedScssContent);
190
+ if (recursiveImports.length) {
191
+ replacedScssContent = replaceImports(processImports(recursiveImports, path.dirname(importPath), workspaceDir, importStorage, true), replacedScssContent);
158
192
  }
159
193
 
160
194
  importResults.push({
@@ -1,8 +1,7 @@
1
1
  const path = require('path');
2
2
 
3
3
  function loadAliases(packageDir, nodeModulesPath, srcDir){
4
- return {
5
- 'src': srcDir + '/src',
4
+ return {
6
5
  '@rws-framework/foundation': path.resolve(packageDir, 'foundation', 'rws-foundation.js')
7
6
  }
8
7
  }
@@ -1,18 +1,18 @@
1
1
  const chalk = require('chalk');
2
+ const path = require('path');
3
+
2
4
  const { RWSConfigBuilder } = require('@rws-framework/console')
3
5
  const { rwsPath } = require('@rws-framework/console');
4
6
  const { _DEFAULT_CONFIG } = require('../../_default.cfg');
5
7
 
6
- async function getBuildConfig(rwsFrontBuildConfig){
7
- const BuildConfigurator = new RWSConfigBuilder(rwsPath.findPackageDir(process.cwd()) + '/.rws.json', {..._DEFAULT_CONFIG, ...rwsFrontBuildConfig});
8
- const _packageDir = rwsPath.findPackageDir(process.cwd());
9
-
8
+ async function getBuildConfig(rwsFrontBuildConfig, _packageDir){
9
+ const BuildConfigurator = new RWSConfigBuilder(path.join(rwsPath.findPackageDir(process.cwd()), '.rws.json'), {..._DEFAULT_CONFIG, ...rwsFrontBuildConfig});
10
10
  const executionDir = rwsPath.relativize(BuildConfigurator.get('executionDir') || rwsFrontBuildConfig.executionDir || process.cwd(), _packageDir);
11
11
  const isWatcher = process.argv.includes('--watch') || false;
12
12
 
13
13
  const isDev = isWatcher ? true : (BuildConfigurator.get('dev', rwsFrontBuildConfig.dev) || false);
14
- const isHotReload = BuildConfigurator.get('hot', rwsFrontBuildConfig.hot);
15
- const isReport = BuildConfigurator.get('report', rwsFrontBuildConfig.report);
14
+ const isHotReload = BuildConfigurator.get('hotReload', rwsFrontBuildConfig.hotReload);
15
+ const isReport = BuildConfigurator.get('pkgReport', rwsFrontBuildConfig.pkgReport);
16
16
  const isParted = BuildConfigurator.get('parted', rwsFrontBuildConfig.parted || false);
17
17
 
18
18
  const partedPrefix = BuildConfigurator.get('partedPrefix', rwsFrontBuildConfig.partedPrefix);
@@ -20,7 +20,7 @@ async function getBuildConfig(rwsFrontBuildConfig){
20
20
 
21
21
  let partedComponentsLocations = BuildConfigurator.get('partedComponentsLocations', rwsFrontBuildConfig.partedComponentsLocations);
22
22
  const customServiceLocations = BuildConfigurator.get('customServiceLocations', rwsFrontBuildConfig.customServiceLocations); //@todo: check if needed
23
- const outputDir = rwsPath.relativize(BuildConfigurator.get('outputDir', rwsFrontBuildConfig.outputDir), _packageDir);
23
+ const outputDir = rwsPath.relativize(BuildConfigurator.get('outputDir', rwsFrontBuildConfig.outputDir), executionDir);
24
24
 
25
25
  const outputFileName = BuildConfigurator.get('outputFileName') || rwsFrontBuildConfig.outputFileName;
26
26
  const publicDir = BuildConfigurator.get('publicDir') || rwsFrontBuildConfig.publicDir;
@@ -37,7 +37,7 @@ async function getBuildConfig(rwsFrontBuildConfig){
37
37
 
38
38
  const devRouteProxy = BuildConfigurator.get('devRouteProxy') || rwsFrontBuildConfig.devRouteProxy;
39
39
 
40
- const tsConfigPath = rwsPath.relativize(BuildConfigurator.get('tsConfigPath') || rwsFrontBuildConfig.tsConfigPath, executionDir);
40
+ const tsConfig = BuildConfigurator.get('tsConfig') || rwsFrontBuildConfig.tsConfig;
41
41
 
42
42
  const rwsPlugins = {};
43
43
 
@@ -67,9 +67,8 @@ async function getBuildConfig(rwsFrontBuildConfig){
67
67
  devTools,
68
68
  devDebug,
69
69
  devRouteProxy,
70
- tsConfigPath,
71
- rwsPlugins,
72
- _packageDir,
70
+ tsConfig,
71
+ rwsPlugins,
73
72
  BuildConfigurator
74
73
  }
75
74
  }
@@ -41,7 +41,7 @@ function setComponentsChunks(clientEntry, RWSComponents = [], isParted = false)
41
41
  }
42
42
 
43
43
  function generateRWSInfoFile(outputDir, automatedEntries) {
44
- const rwsInfoJson = outputDir + '/rws_info.json'
44
+ const rwsInfoJson = path.join(outputDir, '/rws_info.json');
45
45
  fs.writeFile(rwsInfoJson, JSON.stringify({ components: Object.keys(automatedEntries) }, null, 2), () => {});
46
46
  }
47
47
 
@@ -7,7 +7,7 @@ function processEnvDefines(BuildConfigurator, config, devDebug) {
7
7
  'process.env._RWS_BUILD_OVERRIDE': JSON.stringify(BuildConfigurator.exportBuildConfig())
8
8
  }
9
9
 
10
- const rwsDefines = BuildConfigurator.get('rwsDefines') || config.rwsDefines || null;
10
+ const rwsDefines = BuildConfigurator.get('env') || config.env || null;
11
11
 
12
12
  if (rwsDefines) {
13
13
  _rws_defines = { ..._rws_defines, ...rwsDefines }
@@ -1,11 +1,12 @@
1
1
  const chalk = require('chalk');
2
+ const util = require('util');
3
+
4
+
2
5
 
3
6
  module.exports = {
4
- start: (executionDir, tsConfigPath, outputDir, isDev, publicDir, isParted, partedPrefix, partedDirUrlPrefix, devTools, rwsPlugins) => {
5
- console.log(chalk.green('Build started with'))
6
- console.log({
7
- executionDir,
8
- tsConfigPath,
7
+ start: (executionDir, tsConfig, outputDir, isDev, publicDir, isParted, partedPrefix, partedDirUrlPrefix, devTools, rwsPlugins) => {
8
+ console.log(chalk.green('RWS Frontend build started with:'), {
9
+ executionDir,
9
10
  outputDir,
10
11
  dev: isDev,
11
12
  publicDir,
@@ -15,5 +16,11 @@ module.exports = {
15
16
  devtool: devTools,
16
17
  plugins: rwsPlugins
17
18
  });
19
+
20
+ console.log(chalk.blue('\nTSCONFIG:'), util.inspect(tsConfig, {
21
+ depth: null,
22
+ colors: true,
23
+ maxArrayLength: null
24
+ }));
18
25
  }
19
26
  }
@@ -2,20 +2,20 @@ const path = require('path');
2
2
  const fs = require('fs');
3
3
  const os = require('os');
4
4
 
5
+ const { parseWebpackPath } = require('./_parser');
6
+
5
7
  const RWSCssPlugin = require("../../../builder/webpack/rws_scss_plugin");
6
- const plugin = new RWSCssPlugin();
7
- const JSON5 = require('json5');
8
+
8
9
  const chalk = require('chalk');
9
10
  const { timingCounterStart, timingCounterStop } = require('./_timing');
10
- const { rwsRuntimeHelper } = require('@rws-framework/console');
11
+ const { rwsRuntimeHelper, rwsPath } = require('@rws-framework/console');
11
12
 
12
- function getRWSLoaders(packageDir, nodeModulesPath, tsConfigPath, devDebug) {
13
- const scssLoader = packageDir + '/builder/webpack/loaders/rws_fast_scss_loader.js';
14
- const tsLoader = packageDir + '/builder/webpack/loaders/rws_fast_ts_loader.js';
15
- const htmlLoader = packageDir + '/builder/webpack/loaders/rws_fast_html_loader.js';
13
+ function getRWSLoaders(packageDir, executionDir, tsConfig, entrypoint) {
14
+ const scssLoader = path.join(packageDir, 'builder/webpack/loaders/rws_fast_scss_loader.js');
15
+ const tsLoader = path.join(packageDir, 'builder/webpack/loaders/rws_fast_ts_loader.js');
16
+ const htmlLoader = path.join(packageDir, 'builder/webpack/loaders/rws_fast_html_loader.js');
16
17
 
17
-
18
- return [
18
+ const loaders = [
19
19
  {
20
20
  test: /\.html$/,
21
21
  use: [
@@ -30,19 +30,34 @@ function getRWSLoaders(packageDir, nodeModulesPath, tsConfigPath, devDebug) {
30
30
  {
31
31
  loader: 'ts-loader',
32
32
  options: {
33
- transpileOnly: true,
34
- allowTsInNodeModules: true,
35
- configFile: path.resolve(tsConfigPath)
33
+ transpileOnly: false,
34
+ logLevel: "info", // Show more detailed errors
35
+ logInfoToStdOut: true,
36
+ context: executionDir,
37
+ errorFormatter: (message, colors) => {
38
+ const messageText = message.message || message;
39
+ return `\nTS Error: ${messageText}\n`;
40
+ },
41
+ ...tsConfig
36
42
  }
37
43
  },
38
44
  {
39
45
  loader: tsLoader,
46
+ options: {
47
+ rwsWorkspaceDir: executionDir
48
+ }
40
49
  }
41
50
  ],
51
+ include: [
52
+ path.resolve(executionDir, 'src'),
53
+ path.resolve(executionDir, '@dev', 'client', 'src'),
54
+ path.resolve(packageDir, 'src'),
55
+ path.resolve(packageDir, 'foundation', 'rws-foundation.d.ts')
56
+ ],
42
57
  exclude: [
43
58
  /node_modules\/(?!\@rws-framework\/[A-Z0-9a-z])/,
44
59
  /\.debug\.ts$/,
45
- /\.d\.ts$/,
60
+ /\.d\.ts$/
46
61
  ],
47
62
  },
48
63
  {
@@ -51,7 +66,9 @@ function getRWSLoaders(packageDir, nodeModulesPath, tsConfigPath, devDebug) {
51
66
  scssLoader,
52
67
  ],
53
68
  },
54
- ]
69
+ ];
70
+
71
+ return loaders;
55
72
  }
56
73
 
57
74
  function _extractRWSViewDefs(fastOptions = {}, decoratorArgs = {})
@@ -98,7 +115,7 @@ function extractRWSViewArgs(content, noReplace = false) {
98
115
  if (groupIndex === 2) {
99
116
  if (match) {
100
117
  try {
101
- decoratorArgs = JSON5.parse(match);
118
+ decoratorArgs = JSON.parse(JSON.stringify(match));
102
119
  } catch(e){
103
120
  console.log(chalk.red('Decorator options parse error: ') + e.message + '\n Problematic line:');
104
121
  console.log(`
@@ -107,6 +124,8 @@ function extractRWSViewArgs(content, noReplace = false) {
107
124
  console.log(chalk.yellowBright(`Decorator options failed to parse for "${tagName}" component.`) + ' { decoratorArgs } defaulting to null.');
108
125
  console.log(match);
109
126
 
127
+ console.error(e);
128
+
110
129
  throw new Error('Failed parsing @RWSView')
111
130
  }
112
131
  }
@@ -161,18 +180,19 @@ function extractRWSViewArgs(content, noReplace = false) {
161
180
  }
162
181
  }
163
182
 
164
- async function getStyles(filePath, addDependency, templateExists, stylesPath = null, isDev = false) {
183
+ async function getStyles(filePath, rwsWorkspaceDir, addDependency, templateExists, stylesPath = null, isDev = false) {
165
184
  if(!stylesPath){
166
185
  stylesPath = 'styles/layout.scss';
167
186
  }
168
187
 
169
188
  let styles = 'const styles: null = null;'
170
- const stylesFilePath = path.dirname(filePath) + '/' + stylesPath;
189
+ const stylesFilePath = path.join(path.dirname(filePath), stylesPath);
171
190
 
172
191
  if (fs.existsSync(stylesFilePath)) {
173
192
  const scsscontent = fs.readFileSync(stylesFilePath, 'utf-8');
174
193
  timingCounterStart();
175
- const codeData = await plugin.compileScssCode(scsscontent, path.dirname(filePath) + '/styles', null, filePath, !isDev);
194
+ const plugin = new RWSCssPlugin({ rwsWorkspaceDir });
195
+ const codeData = await plugin.compileScssCode(scsscontent, path.join(path.dirname(filePath), 'styles'), null, filePath, !isDev);
176
196
  const elapsed = timingCounterStop();
177
197
  let currentTimingList = rwsRuntimeHelper.getRWSVar('_timer_css');
178
198
 
@@ -193,7 +213,7 @@ async function getStyles(filePath, addDependency, templateExists, stylesPath = n
193
213
  }
194
214
  styles += `const styles = ${templateExists ? 'T.' : ''}css\`${cssCode}\`;\n`;
195
215
 
196
- addDependency(path.dirname(filePath) + '/' + stylesPath);
216
+ addDependency(path.join(path.dirname(filePath), '/', stylesPath));
197
217
  }
198
218
 
199
219
  return styles;
@@ -0,0 +1,118 @@
1
+ // _parser.js
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ function checkIfPackageIsLinked(basePath, packageName) {
6
+ try {
7
+ // Check package.json first
8
+ const packageJsonPath = path.join(basePath, 'package.json');
9
+ if (fs.existsSync(packageJsonPath)) {
10
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
11
+
12
+ // Check if it's in dependencies or devDependencies
13
+ const version = packageJson.dependencies?.[packageName] || packageJson.devDependencies?.[packageName];
14
+
15
+ // If version starts with 'file:' or 'link:', it's linked
16
+ if (version && (version.startsWith('file:') || version.startsWith('link:'))) {
17
+ return {
18
+ isLinked: true,
19
+ source: 'package.json',
20
+ linkPath: version.replace(/^(file:|link:)/, '')
21
+ };
22
+ }
23
+ }
24
+
25
+ // Check yarn.lock
26
+ const yarnLockPath = path.join(basePath, 'yarn.lock');
27
+ if (fs.existsSync(yarnLockPath)) {
28
+ const yarnLockContent = fs.readFileSync(yarnLockPath, 'utf8');
29
+ const packageEntry = yarnLockContent.split('\n\n').find(entry =>
30
+ entry.includes(`"${packageName}@`)
31
+ );
32
+
33
+ if (packageEntry && packageEntry.includes('link:')) {
34
+ const linkMatch = packageEntry.match(/link: (.+)/);
35
+ return {
36
+ isLinked: true,
37
+ source: 'yarn.lock',
38
+ linkPath: linkMatch ? linkMatch[1] : null
39
+ };
40
+ }
41
+ }
42
+
43
+ // Check package-lock.json
44
+ const packageLockPath = path.join(basePath, 'package-lock.json');
45
+ if (fs.existsSync(packageLockPath)) {
46
+ const packageLock = JSON.parse(fs.readFileSync(packageLockPath, 'utf8'));
47
+ const packageInfo = packageLock.dependencies?.[packageName] ||
48
+ packageLock.devDependencies?.[packageName];
49
+
50
+ if (packageInfo && packageInfo.link) {
51
+ return {
52
+ isLinked: true,
53
+ source: 'package-lock.json',
54
+ linkPath: packageInfo.link
55
+ };
56
+ }
57
+ }
58
+
59
+ return {
60
+ isLinked: false,
61
+ source: null,
62
+ linkPath: null
63
+ };
64
+ } catch (e) {
65
+ console.error('Error checking package link status:', e);
66
+ return {
67
+ isLinked: false,
68
+ source: null,
69
+ linkPath: null,
70
+ error: e.message
71
+ };
72
+ }
73
+ }
74
+
75
+ function parseWebpackPath(stack) {
76
+ const currentFileLine = stack.split('\n').find(line => line.includes('_loaders.js'));
77
+ if (!currentFileLine) return null;
78
+
79
+ const match = currentFileLine.match(/\((.+?):\d+:\d+\)/);
80
+ if (!match) return null;
81
+
82
+ const originalPath = match[1];
83
+
84
+ if (originalPath.includes('webpack:')) {
85
+ const [fsPath, webpackPath] = originalPath.split('webpack:');
86
+ const basePath = fsPath.replace('/build/', '/');
87
+
88
+ // Check if @rws-framework/client is linked
89
+ const linkInfo = checkIfPackageIsLinked(basePath, '@rws-framework/client');
90
+
91
+ // Check both possible locations
92
+ const possiblePaths = [
93
+ // Check in @dev/client
94
+ path.join(basePath, '../@dev/client', webpackPath),
95
+ // Check in node_modules
96
+ path.join(basePath, 'node_modules/@rws-framework/client', webpackPath.replace('/client/', '/'))
97
+ ];
98
+
99
+ for (const possiblePath of possiblePaths) {
100
+ if (fs.existsSync(possiblePath)) {
101
+ return {
102
+ original: originalPath,
103
+ fsPath: basePath,
104
+ webpackPath,
105
+ exists: true,
106
+ realPath: fs.realpathSync(possiblePath),
107
+ resolvedPath: possiblePath,
108
+ location: possiblePath.includes('node_modules') ? 'node_modules' : '@dev',
109
+ linkInfo // Include the link information
110
+ };
111
+ }
112
+ }
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+ module.exports = { parseWebpackPath, checkIfPackageIsLinked };
@@ -48,7 +48,7 @@ function getDefinesPlugins(BuildConfigurator, rwsFrontendConfig, devDebug) {
48
48
  ]
49
49
  }
50
50
 
51
- function getBuilderDevPlugins(BuildConfigurator, rwsFrontendConfig, tsConfigPath, devDebug) {
51
+ function getBuilderDevPlugins(BuildConfigurator, rwsFrontendConfig, devDebug) {
52
52
  if(!devDebug?.profiling){
53
53
  return [];
54
54
  }
@@ -63,18 +63,18 @@ function getBuilderDevPlugins(BuildConfigurator, rwsFrontendConfig, tsConfigPath
63
63
  ]
64
64
  }
65
65
 
66
- function getBuilderOptimPlugins(BuildConfigurator, rwsFrontendConfig, tsConfigPath) {
66
+ function getBuilderOptimPlugins(BuildConfigurator, rwsFrontendConfig) {
67
67
  return [
68
68
 
69
69
  ]
70
70
  }
71
71
 
72
- function addStartPlugins(rwsFrontendConfig, BuildConfigurator, devDebug, isHotReload, isReport, tsConfigPath) {
72
+ function addStartPlugins(rwsFrontendConfig, BuildConfigurator, devDebug, isHotReload, isReport) {
73
73
 
74
74
  RWS_WEBPACK_PLUGINS_BAG.add([
75
75
  ...getDefinesPlugins(BuildConfigurator, rwsFrontendConfig, devDebug),
76
- ...getBuilderDevPlugins(BuildConfigurator, rwsFrontendConfig, tsConfigPath, devDebug),
77
- ...getBuilderOptimPlugins(BuildConfigurator, rwsFrontendConfig, tsConfigPath),
76
+ ...getBuilderDevPlugins(BuildConfigurator, rwsFrontendConfig, devDebug),
77
+ ...getBuilderOptimPlugins(BuildConfigurator, rwsFrontendConfig),
78
78
  ...getPackageModPlugins()
79
79
  ]);
80
80
 
@@ -84,7 +84,7 @@ function addStartPlugins(rwsFrontendConfig, BuildConfigurator, devDebug, isHotRe
84
84
  }
85
85
 
86
86
  RWS_WEBPACK_PLUGINS_BAG.add(new HtmlWebpackPlugin({
87
- template: publicDir + '/' + publicIndex,
87
+ template: path.join(publicDir, '/', publicIndex),
88
88
  }));
89
89
  }
90
90
 
@@ -1,28 +1,26 @@
1
1
  const TerserPlugin = require('terser-webpack-plugin');
2
2
  const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
3
3
 
4
-
5
4
  function getRWSProductionSetup(optimConfig){
6
-
7
5
  return {
8
6
  ...optimConfig,
9
7
  minimize: true,
10
8
  minimizer: [
11
9
  new TerserPlugin({
10
+ parallel: true,
11
+ extractComments: false,
12
12
  terserOptions: {
13
13
  keep_classnames: true, // Prevent mangling of class names
14
- mangle: false, //@error breaks FAST view stuff if enabled for all assets
14
+ mangle: false, //@error breaks FAST view stuff if enabled for all assets
15
15
  compress: {
16
16
  dead_code: true,
17
- pure_funcs: ['console.log', 'console.info', 'console.warn']
17
+ pure_funcs: ['console.log', 'console.info', 'console.warn']
18
18
  },
19
- output: {
19
+ format: {
20
20
  comments: false,
21
- beautify: false
22
- },
23
- },
24
- extractComments: false,
25
- parallel: true,
21
+ beautify: false
22
+ }
23
+ }
26
24
  }),
27
25
  new CssMinimizerPlugin({
28
26
  minimizerOptions: {
@@ -12,7 +12,7 @@ const _defaultOpts = {
12
12
  }
13
13
  }
14
14
 
15
- const externals = (declaredCodeBase, nodeModules, automatedChunks, externalOptions = _defaultOpts) => ({context, request}, callback) => {
15
+ const externals = (pkgPath, declaredCodeBase, nodeModules, automatedChunks, externalOptions = _defaultOpts) => ({context, request}, callback) => {
16
16
  let theOptions = _defaultOpts;
17
17
 
18
18
  if(externalOptions !== null){
@@ -36,7 +36,7 @@ const externals = (declaredCodeBase, nodeModules, automatedChunks, externalOptio
36
36
 
37
37
  const frontendDirs = [
38
38
  codeBase,
39
- path.resolve(__dirname,'..','..','..')
39
+ pkgPath
40
40
  ];
41
41
 
42
42
  const inFrontendContext = frontendDirs.some(dir => context.startsWith(dir)) ||
@@ -3,7 +3,6 @@ const path = require('path');
3
3
 
4
4
  function createWebpackConfig(
5
5
  executionDir,
6
- clientPkgPath,
7
6
  _packageDir,
8
7
  isDev,
9
8
  devTools,
@@ -15,10 +14,11 @@ function createWebpackConfig(
15
14
  automatedChunks,
16
15
  modules_setup,
17
16
  aliases,
18
- tsConfigPath,
17
+ tsConfig,
19
18
  WEBPACK_PLUGINS,
20
19
  rwsExternals,
21
- devExternalsVars
20
+ devExternalsVars,
21
+ entrypoint
22
22
  ) {
23
23
  return {
24
24
  context: executionDir,
@@ -41,18 +41,12 @@ function createWebpackConfig(
41
41
  }
42
42
  },
43
43
  module: {
44
- rules: getRWSLoaders(clientPkgPath, path.resolve(_packageDir, 'node_modules'), tsConfigPath, devDebug),
44
+ rules: getRWSLoaders(_packageDir, executionDir, tsConfig, entrypoint),
45
45
  },
46
46
  plugins: WEBPACK_PLUGINS,
47
- externals: rwsExternals(executionDir, modules_setup, automatedChunks, {
47
+ externals: rwsExternals(_packageDir, executionDir, modules_setup, automatedChunks, {
48
48
  _vars: devExternalsVars
49
- }),
50
- cache: {
51
- type: 'filesystem',
52
- buildDependencies: {
53
- config: [__filename],
54
- },
55
- }
49
+ })
56
50
  }
57
51
  }
58
52
 
@@ -5,7 +5,7 @@ const { rwsPath } = require('@rws-framework/console');
5
5
  const path = require('path');
6
6
  const fs = require('fs');
7
7
 
8
- function setupTsConfig(tsConfigPath, executionDir, userAliases = {}) {
8
+ function setupTsConfig(tsConfigPath, executionDir, pkgPath, userAliases = {}) {
9
9
 
10
10
  if (!fs.existsSync(tsConfigPath)) {
11
11
  throw new Error(`Typescript config file "${tsConfigPath}" does not exist`);
@@ -16,16 +16,15 @@ function setupTsConfig(tsConfigPath, executionDir, userAliases = {}) {
16
16
  try {
17
17
  let tsConfig = JSON.parse(tsConfigContents);
18
18
 
19
- const declarationsPath = path.resolve(__dirname, '..', 'types') + '/declarations.d.ts';
20
- const foundationPath = path.resolve(__dirname, '..', 'foundation');
21
- const testsPath = path.resolve(__dirname, '..', 'tests');
19
+ const declarationsPath = path.resolve(pkgPath, 'types') + '/declarations.d.ts';
20
+ const foundationPath = path.resolve(pkgPath, 'foundation');
21
+ const testsPath = path.resolve(pkgPath, 'tests');
22
22
 
23
23
 
24
24
  const relativeDeclarationsPath = path.relative(path.dirname(tsConfigPath), declarationsPath);
25
25
  const relativeTestsPath = path.relative(path.dirname(tsConfigPath), testsPath);
26
26
  const relativeFoundationPath = path.relative(path.dirname(tsConfigPath), foundationPath);
27
27
 
28
-
29
28
  const includedMD5 = [];
30
29
  const srcPath = 'src/index.ts';
31
30
 
@@ -93,8 +92,6 @@ function setupTsConfig(tsConfigPath, executionDir, userAliases = {}) {
93
92
 
94
93
  tsPaths[alias] = [path.relative(executionDir, aliasPath)];
95
94
 
96
- console.log({alias, x: tsPaths[alias]});
97
-
98
95
  changedPaths = true;
99
96
  }
100
97
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rws-framework/client",
3
3
  "private": false,
4
- "version": "2.14.0",
4
+ "version": "2.15.0",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
7
7
  "docs": "typedoc --tsconfig ./tsconfig.json"
@@ -59,6 +59,7 @@
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
+ "emoji-regex": "^10.3.0",
62
63
  "eslint": "^6.0.0",
63
64
  "file-loader": "^6.2.0",
64
65
  "html-webpack-plugin": "^5.5.3",
@@ -67,36 +68,35 @@
67
68
  "minimatch": "^9.0.4",
68
69
  "node-sass": "^9.0.0",
69
70
  "raw-loader": "^4.0.2",
70
- "source-map": "^0.7.4",
71
- "source-map-support": "^0.5.21",
72
- "stacktrace-gps": "^3.1.2",
73
71
  "sass": "1.69.7",
72
+ "sass-embedded": "^1.83.4",
74
73
  "sass-loader": "^13.3.2",
75
74
  "scss-loading-animations": "^1.0.1",
76
- "sass-embedded": "^1.83.4",
75
+ "source-map": "^0.7.4",
76
+ "source-map-support": "^0.5.21",
77
77
  "speed-measure-webpack-plugin": "^1.5.0",
78
+ "stacktrace-gps": "^3.1.2",
78
79
  "style-loader": "^3.3.3",
79
80
  "terser-webpack-plugin": "^5.3.9",
80
81
  "ts-loader": "^9.4.4",
81
82
  "ts-node": "^10.9.1",
83
+ "ts-transformer-keys": "^0.4.4",
84
+ "tsc-watch": "^6.0.4",
82
85
  "tsconfig-paths": "^4.2.0",
83
86
  "tsconfig-paths-webpack-plugin": "^4.1.0",
87
+ "tslib": "^2.6.2",
84
88
  "typedoc": "^0.25.4",
85
89
  "typedoc-plugin-mermaid": "^1.10.0",
86
90
  "typedoc-plugin-not-exported": "^0.1.6",
87
91
  "typedoc-plugin-rename-defaults": "^0.7.0",
88
92
  "typedoc-theme-hierarchy": "^4.1.2",
89
93
  "typescript": "^5.1.6",
90
- "url-loader": "^4.1.1",
91
- "emoji-regex": "^10.3.0",
92
- "ts-transformer-keys": "^0.4.4",
93
- "tsc-watch": "^6.0.4",
94
- "tslib": "^2.6.2",
95
94
  "uglify-js": "^3.17.4",
95
+ "url-loader": "^4.1.1",
96
96
  "vite": "^6.0.11",
97
- "webpack": "^5.86.0",
97
+ "webpack": "^5.97.1",
98
98
  "webpack-bundle-analyzer": "^4.10.1",
99
- "webpack-cli": "^5.1.4",
99
+ "webpack-cli": "^6.0.1",
100
100
  "webpack-dev-server": "^4.15.1",
101
101
  "webpack-node-externals": "^3.0.0"
102
102
  },
@@ -106,4 +106,4 @@
106
106
  "overrides": {
107
107
  "lodash": "^4.17.21"
108
108
  }
109
- }
109
+ }
@@ -0,0 +1,158 @@
1
+ # RWS Grid System
2
+ A flexible SASS-based grid system providing responsive column layouts with simple syntax.
3
+
4
+ ## Table of Contents
5
+ - [Installation](#installation)
6
+ - [Breakpoints](#breakpoints)
7
+ - [Basic Usage](#basic-usage)
8
+ - [Mixins](#mixins)
9
+ - [Examples](#examples)
10
+
11
+ ## Installation
12
+ Import the mixins file into your SASS project:
13
+
14
+ ```scss
15
+ @import '@rws-mixins';
16
+ ```
17
+
18
+ ## Breakpoints
19
+ The system uses three main breakpoint values:
20
+
21
+ | Name | Default Width | CSS Variable |
22
+ |------|---------------|-------------|
23
+ | md | 1200px | --rws-md-width |
24
+ | sm | 992px | --rws-sm-width |
25
+ | xs | 768px | --rws-xs-width |
26
+
27
+ Breakpoints can be customized using CSS variables or directly in the `$breakpoints` map.
28
+
29
+ ## Basic Usage
30
+
31
+ ### Grid Container
32
+ ```scss
33
+ .container {
34
+ @include rws-gr; // Basic flex container
35
+ @include rws-gr-gap(20px); // Adds gaps between columns
36
+ }
37
+ ```
38
+
39
+ ### Responsive Columns
40
+ ```scss
41
+ .column {
42
+ @include rws-gr-col(3, 4, 6, 12);
43
+ // 3 columns on large screens
44
+ // 4 columns on medium screens (< 1200px)
45
+ // 6 columns on small screens (< 992px)
46
+ // 12 columns on extra small screens (< 768px)
47
+ }
48
+ ```
49
+
50
+ ## Mixins
51
+
52
+ ### rws-gr
53
+ Creates a basic flexbox container with wrap enabled.
54
+ ```scss
55
+ @include rws-gr;
56
+ ```
57
+
58
+ ### rws-gr-gap($gap)
59
+ Adds spacing between columns.
60
+ ```scss
61
+ @include rws-gr-gap(20px);
62
+ ```
63
+
64
+ ### rws-gr-col($lg, $md, $sm, $xs)
65
+ Defines column width for different breakpoints.
66
+ - `$lg`: width for large screens (default 12)
67
+ - `$md`: width for medium screens (optional)
68
+ - `$sm`: width for small screens (optional)
69
+ - `$xs`: width for extra small screens (optional)
70
+
71
+ ### rws-gr-align($h, $v)
72
+ Controls alignment of items in the container.
73
+ - `$h`: horizontal alignment (default flex-start)
74
+ - `$v`: vertical alignment (default top)
75
+
76
+ ### rws-gr-center
77
+ Centers the container relative to its parent.
78
+
79
+ ## Examples
80
+
81
+ ### Basic Layout with Gaps
82
+ ```scss
83
+ .container {
84
+ @include rws-gr;
85
+ @include rws-gr-gap(20px);
86
+ @include rws-gr-center;
87
+
88
+ .column {
89
+ @include rws-gr-col(4, 6, 12);
90
+ }
91
+ }
92
+ ```
93
+
94
+ ### Aligned Layout
95
+ ```scss
96
+ .aligned-container {
97
+ @include rws-gr;
98
+ @include rws-gr-align(center, center);
99
+
100
+ .column {
101
+ @include rws-gr-col(3);
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Complete Responsive Layout Example
107
+ ```scss
108
+ .page-layout {
109
+ @include rws-gr;
110
+ @include rws-gr-gap(30px);
111
+ @include rws-gr-center;
112
+
113
+ .sidebar {
114
+ @include rws-gr-col(3, 4, 12);
115
+ }
116
+
117
+ .main-content {
118
+ @include rws-gr-col(9, 8, 12);
119
+ }
120
+
121
+ .footer {
122
+ @include rws-gr-col(12);
123
+ }
124
+ }
125
+ ```
126
+
127
+ ## Advanced Tips
128
+
129
+ ### Custom Breakpoints
130
+ You can override default breakpoints using CSS variables:
131
+ ```css
132
+ :root {
133
+ --rws-md-width: 1400px;
134
+ --rws-sm-width: 1024px;
135
+ --rws-xs-width: 800px;
136
+ }
137
+ ```
138
+
139
+ ### Column Calculation
140
+ The system uses a 12-column grid by default. Column widths are calculated using:
141
+ ```scss
142
+ width = (100% / 12) * columns
143
+ ```
144
+
145
+ ### Best Practices
146
+ 1. Always start with mobile layout first
147
+ 2. Use semantic class names
148
+ 3. Avoid deeply nested grids
149
+ 4. Consider using the gap mixin for consistent spacing
150
+ 5. Test layouts across different screen sizes
151
+
152
+ ## Browser Support
153
+ This grid system relies on modern CSS features including:
154
+ - Flexbox
155
+ - CSS Custom Properties (CSS Variables)
156
+ - CSS calc()
157
+
158
+ Ensure your target browsers support these features or include appropriate fallbacks.
@@ -0,0 +1,50 @@
1
+ // Import the new grid system (if needed - depends on your build setup)
2
+ // @import 'grid';
3
+
4
+ // Keep the legacy breakpoints for backward compatibility
5
+ $mediaQuerySteps: $breakpoints;
6
+
7
+ // Legacy mixins using new system
8
+
9
+ // Mixin for the grid container
10
+ @mixin grid-container() {
11
+ @include rws-gr;
12
+ }
13
+
14
+ @mixin grid-container-gap($gap) {
15
+ @include rws-gr-gap($gap);
16
+ }
17
+
18
+ // Internal helper kept for backward compatibility
19
+ @mixin internal-grid-column($columns: 12) {
20
+ @include _gr-col-calc($columns);
21
+ }
22
+
23
+ // Legacy column mixins using new system
24
+ @mixin grid-column($columns: 12) {
25
+ @include rws-gr-col($columns);
26
+ }
27
+
28
+ // Two breakpoint version
29
+ @mixin grid-column($columns: 12, $mdColumns: 12) {
30
+ @include rws-gr-col($columns, $mdColumns);
31
+ }
32
+
33
+ // Three breakpoint version
34
+ @mixin grid-column($columns: 12, $mdColumns: 12, $smColumns: 12) {
35
+ @include rws-gr-col($columns, $mdColumns, $smColumns);
36
+ }
37
+
38
+ // Four breakpoint version
39
+ @mixin grid-column($columns: 12, $mdColumns: 12, $smColumns: 12, $xsColumns: 12) {
40
+ @include rws-gr-col($columns, $mdColumns, $smColumns, $xsColumns);
41
+ }
42
+
43
+ // Mixins for grid alignment
44
+ @mixin grid-flex-align-items($horizontal, $vertical: top) {
45
+ @include rws-gr-align($horizontal, $vertical);
46
+ }
47
+
48
+ @mixin center-container() {
49
+ @include rws-gr-center;
50
+ }
package/tsconfig.json CHANGED
@@ -1,31 +1,20 @@
1
- {
2
- "compilerOptions": {
3
- "baseUrl": "./",
4
- "experimentalDecorators": true,
5
- "emitDecoratorMetadata": true,
6
- "target": "ES2018",
7
- "module": "es2022",
8
- "moduleResolution": "node",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "resolveJsonModule": true,
12
- "outDir": "dist/src",
13
- "strictNullChecks": false,
14
- "skipLibCheck": true,
15
- "allowSyntheticDefaultImports": true,
16
- "sourceMap": true,
17
- "declaration": true,
18
- "lib": ["DOM", "ESNext"],
19
- },
20
- "paths": {
21
- "@rws-framework/client": ["src"],
22
- "@rws-framework/foundation": ["foundation"]
23
- },
24
- "include": [
25
- "src/index.ts",
26
- "types/docs-typings.d.ts"
27
- ],
28
- "exclude": [
29
- "node_modules"
30
- ]
31
- }
1
+ {
2
+ "compilerOptions": {
3
+ "experimentalDecorators": true,
4
+ "emitDecoratorMetadata": true,
5
+ "target": "ES2018",
6
+ "module": "es2022",
7
+ "moduleResolution": "node",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "sourceMap": true,
11
+ "outDir": "dist",
12
+ "strictNullChecks": false,
13
+ "allowSyntheticDefaultImports": true,
14
+ "lib": [
15
+ "DOM",
16
+ "ESNext",
17
+ "WebWorker"
18
+ ]
19
+ }
20
+ }