Compile SASS with webpack into multiple CSS files - javascript

Consider a webpack 4 built project with the following structure that has ./blocks/index.js as the main entry point:
├── assets
│ ├── css
│ │ ├── editor.blocks.css
│ │ ├── style.blocks.css
│ ├── js
│ │ ├── editor.blocks.js
├── blocks
│ ├── block1
│ │ ├── editor.scss
│ │ ├── style.scss
│ │ ├── index.js
│ ├── block2
│ │ ├── editor.scss
│ │ ├── style.scss
│ │ ├── index.js
│ ├── block3
│ │ ├── editor.scss
│ │ ├── style.scss
│ │ ├── index.js
│ ├── index.js
The SASS files are imported into the index.js file inside each block folder.
When webpack runs it should:
Concatenate and compile all style.scss files to ./assets/css/style.blocks.css.
Concatenate and compile all editor.scss files to ./assets/css/editor.blocks.css.
At the moment, it kind of works but instead of concatenating and compiling all style.scss files into ./assets/css/style.blocks.css and all editor.scss files into ./assets/css/editor.blocks.css it seems to grab the SASS from the LAST block folder only (`./blocks/block3').
This indicates that style.blocks.css and editor.blocks.css are continuously being overwritten which is incorrect. I think the loader that writes the final two CSS files may need to be a plugin instead? I've tried the MiniCssExtractPlugin but couldn't get that to output two CSS files based on multiple SASS files.
Here's the full repo: https://github.com/dgwyer/multiple-webpack-css-files

Managed to get this working in webpack 4 with the MiniCssExtractPlugin webpack plugin, with a minor workaround which shouldn't be necessary in webpack 5 apparently.
https://github.com/dgwyer/multiple-webpack-css-files

Related

Node & Typescript; Atomizing IMPORT/EXPORT

Good day!
I'm Working on a personnel projet. A backend using node and typescript.
I've been looking at some architectures and I choose my data layer to be a factory pattern reflecting table operation. In a class, I can wrap up most queries in fonction using 10-20 line per operations. But I'm not sure if I will go with the same pattern for the business layer
Data
├── connections
│ └── mysql.ts
├── models
│ └── user.model.ts
│ └── product.model.ts
└── tables
└── user.table.ts
└── product.table.ts
└── order.table.ts
Because I dont validate parameters(done in business layer) this pattern works fine because query functions or kept fairly small. Functions only return's a result or null. Then Business layer will determine the proper error message(not found, login failed, product is back order....etc)
Now, because business layer require more logics. Thus more lines of code for parameters validation, permissions, data queries, other API calls, error handling ... etc. I strongly think I should use the modules mechanism. Wrapping up a single method in a file. Then only import the business function to an entry point.
Business
├── procedures
│ ├── authentication
│ │ ├── connections.ts
│ │ ├── delete.ts
│ │ ├── login.ts
│ │ ├── logout.ts
│ │ ├── signup.ts
│ │ └── suspend.ts
│ ├── product
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── find.ts
│ │ ├── read.ts
│ │ ├── reserve.ts
│ │ ├── update_description.ts
│ │ ├── update_price.ts
│ │ └── update.ts
│ └── user
│ ├── create.ts
│ ├── delete.ts
│ ├── find.ts
│ ├── read.ts
│ └── update.ts
└── validations
├── authentication
│ ├── connections.ts
│ ├── delete.ts
│ ├── login.ts
│ ├── logout.ts
│ ├── signup.ts
│ └── suspend.ts
├── product
│ ├── create.ts
│ ├── delete.ts
│ ├── find.ts
│ ├── read.ts
│ ├── reserve.ts
│ ├── update_description.ts
│ ├── update_price.ts
│ └── update.ts
└── user
├── create.ts
├── delete.ts
├── find.ts
├── read.ts
└── update.ts
Business layer will be consume by Express routes(no details need it here).
I segmented my validations to reflect the same structure as the procedures directory because AJV validation schema can get pretty big.
I anticipate about 20 Business object with an average of 7 fonctions each. Times 2 for validation. For a total average of 240 files for the business layer.
So, my questions is. Is atomizing business function using import/export in a single file per business function a good practice and will it diminish performance?
RTFMed lots of howto's on import/export but cant seem to find straight answer or performance concern.

Configure Rollup (under Vite) build to create separate bundles with theirs assets

Need your help )
I'm stuck with question - how to configure Rollup build to achieve next build structure.
For example - let's assume that folder structure (it's possible to change it) is:
├── src/
│ ├── common-assets/
│ │ └── ...
│ └-- sections/
│ ├── first-section/
│ │ ├── first-app/
│ │ │ ├── app/
│ │ │ │ ├── app-assets/
│ │ │ │ │ └── ...
│ │ │ │ ├── app-components/
│ │ │ │ │ └── ...
│ │ │ │ └-- ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ ├── second-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ └-- ...
│ ├── second-section/
│ │ ├── first-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ ├── index.html
│ │ ├── second-app/
│ │ │ ├── app/
│ │ │ └── ...
│ │ │ ├── app.ts
│ │ │ └── index.html
│ │ └-- ...
│ └-- ...
├── index.html
├── main.ts
├── package.json
└── vite.config.ts
Folder sections consists of group folders. Each group folder (first-section, second-section, ...) groups apps of particular kind.
That's what I need to get after build done inside dist directory:
├── first-section/
│ ├── first-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ ├── second-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ └-- ...
├── second-section/
│ ├── first-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ ├── second-app/
│ │ ├── app-assets/
│ │ │ └── ...
│ │ ├── common-assets/
│ │ │ └── ...
│ │ ├── bundle.js
│ │ └── index.html
│ └-- ...
└-- ...
So, each *-section directory should includes common-assets and it's own index.html + bundle.js files.
Each app (first-app, second-app, ...) will be used and served as separate application (with it's own store/routing/etc).
I am struggling as well to do this with vite. I think vite is not intended for this usecase. There is a workaround I did, that maybe you can adapt to your purposes.
Basically, I have two html files I want to fill: app1.html and app2.html.
Each app's source code is in its own directory: src/app1 and src/app2.
The apps share very few resources, but I still want to build those two in one go.
My structure is as follows:
├── app1.html
├── app2.html
├── src
│ ├── app1
│ │ ├── App.svelte
│ │ ├── components
│ │ │ └── Component.svelte
│ │ └── main.ts
│ ├── app2
│ │ ├── App.svelte
│ │ ├── components
│ │ │ └── Component.svelte
│ │ └── main.ts
│ ├── shared
│ │ ├── global.css
│ │ └── shared.ts
│ └── vite-env.d.ts
├── svelte.config.js
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
You can see there are two separate apps: src/app1 and src/app2 with similar structure.
I could not find a way to build them separately using only one call to defineConfig, so basically I build the apps separately, using the emptyOutDir: false. This way I won't lose one build when doing the other.
Then, I created some scripts in my package.json:
"scripts": {
"build": "vite build",
"build:app1": "vite build",
"build:app2": "vite build",
"build:all": "pnpm build:app1 && pnpm build:app2",
...
},
The good part about this, is that from vite.config.ts i can access the name of the command using process.env.npm_lifecycle_event. It will be set to build:app1 if I do pnpm build:app1. I can use this to choose which part of the source code to build.
This is my vite.config.ts:
import { defineConfig } from "vite";
import { svelte } from "#sveltejs/vite-plugin-svelte";
const buildScript = process.env.npm_lifecycle_event;
const app = buildScript.includes(":") ? buildScript.split(":")[1] : "app1";
const buildConfig = {
rootHtml: `./${app}.html`,
entryFileNames: `${app}/${app}.js`,
assetFileNames: `${app}/${app}.[ext]`,
};
export default defineConfig({
plugins: [svelte()],
build: {
rollupOptions: {
input: { app: buildConfig.rootHtml },
output: {
entryFileNames: buildConfig.entryFileNames,
assetFileNames: buildConfig.assetFileNames,
},
},
emptyOutDir: false,
},
server: { open: buildConfig.rootHtml },
});
After running pnpm build:all, the dist folder should look like this:
dist
├── app1
│ ├── app1.js
│ └── app1.css
├── app1.html
├── app2
│ ├── app2.js
│ └── app2.css
└── app2.html
I hope this helps. I may try to use rollup instead of vite to see if I can do it more elegantly, but this workaround helped me achieve my goal.

Character * in dynamic import

Good morning everyone, I have a project with the following structure:
intranet
├── modulos
│ ├── almacen
│ │ ├── views
│ │ └── route
│ │ └── index.js
│ │
│ ├── ventas
│ │ ├── views
│ │ └── route
│ │ └── index.js
│ │
│ └── compras
│ ├── views
│ ├── route
│ └── index.js
│
├── route
│ └── index.js
├── store
│ └── index.js
├── ...
The modules folder will have all the modules that I will be connecting to the project, the point is that all the subfolders will have the views, route, etc. subfolders. In turn, in the route folder there will always be an index.js file.
Now in the intranet > route > index file I want to do the import as follows.
import("../modulos/*/route/index").then(module => {
console.log(module);
});
This in order to carry out a self-import of those modules that it finds. The problem is that I get an error because apparently the character * (asterisk) is not allowed inside the import.
I will appreciate the help you give me. Thank you.
This is not possible you have to iterate over all directories in 'modulos'
// pseudo code
for(const folder in modulos_subfolders) {
import(``../modulos/${folder}/route/index`)
}

How to add django back-end after making a frontend website with reactjs?

I made the front-end of my website with the Materialize framework and ReactJS to make it dynamic.
My goal is to make a upvote/downvote system so I need a back-end ORM to use with a database.
I decided to go with Django as I'm more experienced with python, but when I was following a tutorial, I did the command:
npx create-react-app frontend
with the intention of replacing the new files with my "homemade frontend" to make it work except the directory structures were completely different.
Tree made with the command:
├── frontend
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ └── manifest.json
│ ├── README.md
│ ├── node_modules
│ ├── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── App.test.js
│ │ ├── index.css
│ │ ├── index.js
│ │ ├── logo.svg
│ │ └── registerServiceWorker.js
My original frontend tree:
├── frontend
│ ├── Components
│ ├── index.html
│ ├── css
│ │ ├── style.css
│ │ ├── materialize.css
│ │ └── materialize.min.css
│ ├── README.md
│ ├── node_modules
│ ├── js
│ │ ├── init.js
│ │ ├── materialize.js
│ │ └── materialize.min.js
│ ├── src
│ │ └── word_card.js
I feel like the new version of my frontend is based with the idea of making everything with ReactJS in opposition with my old one which only has ReactJS as a supplement.
How do I use django as a backend in this case?
Thanks a lot for taking of your time to help me!
If I understand your question correctly, you are now following a React with Django tutorial, but you have become stuck because the structure of the React app in the tutorial is different to the structure you have already created.
The way that you use Django is the same in either case. You are making a decoupled application with separation of concerns between the front and back end. Django doesn't know or care how your front end is structured.
If you are new to Django I would suggest you start by following the official Django tutorial and then move on to the official Django REST framework tutorial.
https://docs.djangoproject.com/en/2.2/intro/tutorial01/
https://www.django-rest-framework.org/tutorial/1-serialization/

How to install grunt outside of a project and run tasks from the project directory

I'm watching this series of tutorials here and I can see that the grunt ( not the grunt-cli ) files are stored in the project root.
I see that this is normally the case but wanted to put my files elsewhere.
Is there a way to do this. Obviously I could run the init to create the package.json file in say /grunt and do the install there, but would it be relatively easy to tell it how to interface with my project /root/project.
Here is an potential example of your structure :
main-folder
├── package.json
├── Gruntfile.js
├── grunt
│ ├── config.js
│ ├── config
│ │ │ ├── copy.js
│ │ │ ├── sass.js
│ │ │ ├── sync.js
│ │ │ ├── linkAsset.js
│ │ │ └── uglify.js
│ ├── register
│ │ │ ├── compileAssets.js
│ │ │ ├── linkAssets.js
│ │ │ ├── build.js
│ │ │ └── buildProd.js
├── project-1
│ └── folders and files ...
├── project-2
│ └── folders and files ...
package.json : contains all your grunt-plugins dependencies and other useful npm modules
Gruntfile.js : load and configure all tasks in grunt/config and grunt/register folder
Read this if you want to have more information to setup this configuration of grunt : How to create and organise config and register grunt tasks
Configuration file :
I recommend you also to use a configuration file (E.g : main-folder/grunt/config.js) file to register some shortcut, variables to make your grunt tasks more dynamic.
Example :
var version = '0.1.0';
var project1Dir = 'project-1';
var project2Dir = 'project-2';
module.exports.version = version;
module.exports.project1Dir = project1Dir;
module.exports.project2Dir = project2Dir;
And import this config in each task with : var config = require('../config');. It will be easy to refactor the code if you rename for example the folder project1.
Run tasks :
Now when you are working in your directory (main-folder/project1or main-folder/project2) and entering your grunt command, use b flag to tell to grunt where is your Gruntfile.js file.
Example :
grunt -b ../ build
You can also configure in the code this behavior. Read Grunt documentation for more information : Grunt CLI - b flag

Categories

Resources