VueJS: Trying to compile two CSS files in /dist - javascript

I just began using Vue and I'm hitting a wall while trying to compile SCSS into separate files. I understand that any SCSS that I'm writing within components will be compiled into a single file (/dist/css/app[hash].css), but I would like separate files which aren't imported into any component for external use.
I have several SCSS files (frames.scss, lists.scss, and tables.scss ) that I would like to be compiled, minified, and prefixed into their own CSS files alongside the aforementioned CSS file.
I would like the build structure to look something like this (with the external CSS file existing alongside the app CSS file):
dist/
css/
app[hash].css
frames.css
lists.css
tables.css
I have very little experience with Webpack, so my vue.config.js file is currently empty and my postcss.config.js file is below:
module.exports = {
plugins: {
autoprefixer: {}
}
}
I've searched all over StackOverflow for a solution to no avail, so any help would be greatly appreciated!

For webpack 4, I think you want to look at mini-css-extract-plugin.
its a webpack plugin that, by, default, creates different files per input. You can use this with scss as you would expect. https://stackoverflow.com/a/53180597/6646536 might be a good example.
There is a similar tool i've used for webpack 3 here:
https://github.com/webpack-contrib/extract-text-webpack-plugin

Related

webpack resolve error with packaged css file referencing an image

I'm working on a Vue component library built via VueCLI (and using Storybook Js, Bulma, and Buefy) and I am having issues consuming the CSS downstream. Specifically when I import the CSS file from my package, I am getting Webpack errors with referenced images.
For example, in my upstream src scss files I have a file called "notice-badge.scss" and am referencing background images like so:
.notice-badge img {
background-image: url('#/assets/img/warning-dark.svg');
}
and my src directory structure looks like:
my-app/
|--src/
|--assets/
|--scss/
|-- notice-badge.scss
|--img/
|--warning-dark.svg
|--fonts/
|--vue-components/
and I build the packages with this command which produces no errors.
vue-cli-service build --target lib --name my-ui-components ./src/index.ts
This outputs my JS, a CSS file, and 2 directories (img and fonts) into my "dist" directory. The images listed in my errors are infact inthere.
So over in another Vue cli app (and later Nuxt) I will be importing the CSS file and Vue components but I am getting a "can't resolve" error on that warning-dark.svg file:
Can't resolve /img/warning-dark.a45b259b.svg in /Users/myname/sites/my-app/ui-components/dist. My package also contains font awesome font files too (a business decision to include this all up stream)
So how can I get my downstream Vue CLI app to resolve the images and fonts referenced inside my node_modules dir?
You have (at least) 3 options:
Inline the images/fonts as data URLs.
Use a relative path in the output and require apps that install your package to move the image directory to the same path as the built CSS file.
Don't ship built CSS, but instead source SCSS files. That way file loading/moving can be handled with WebPack configuration in the app that uses it (using file_loader. You can include example configuration in your package to make this easier.
If you're writing a Vue component library, it probably makes most sense to use method 3. However from your description it seems like this may not be an option (the business decision you mention). Method 2 might be viable but I didn't try it nor seen someone else suggest it.
Inline
This method probably is easiest and has best performance. If your other SVGs are similar to the examples, it seems like they should all be relatively small files. There's few reasons for a component library to ship big images, so this might be sufficient for your use case.
If you're using WebPack 5, you can inline assets using "Asset Modules".
module: {
rules: [
{
test: /\.svg/,
type: 'asset/inline'
}
]
}
If you tried this, you may have run into the following problem.
Since Sass implementations don't provide url rewriting, all linked
assets must be relative to the output.
If you pass the generated CSS on to the css-loader, all urls must be
relative to the entry-file (e.g. main.scss).
If you're just generating CSS without passing it to the css-loader, it must be relative to your web root.
You can try replacing url('#/assets/img/warning-dark.svg') with url('../img/warning-dark.svg') (or whatever the path relative to the entrypoint is). Does it now properly inline them?

Webpack project with mutliple html / js / css files

I think that I've got how Webpack works. My problem is: Most tutorials/examples are based on a single index.html. So, how would I organize my webpack.config.js and directory structure for multiple pages?
Let's assume that I need the following things:
index.html with a css and js file
dashboard.html with a css and js file
profile.html with a css and js file
And here is what I don't get:
How would you structure your src and dist folder?
How do I have to configure Webpack? Probably with HtmlWebpackPlugin(?)
Is a single index.js file enough as entry point / How does one structure the index.js file / How do ES6 projects look in general?
A sample project would help a lot. A project with more than just an example index.html file.
Have a good day! :)
I think u can do that by convert html+js+css into web component and u can do that easily by a framework , i think Vue js give very good boilerplate full Webpack template to let u do that just start to think about the other page as a new component remember that u r using webpack to get a bundle
So you can have one watch output multiple bundle types by passing in a command line arg to build the right bundle. There can be multiple entry points in webpack but webpack is only build to output one bundle. So, to solve this issue I figured passing a command line arg to webpack is a clean way of having multiple bundle possibilities while maintaining only one config file.
To see how this can be accomplished checkout...
https://www.hipstercode.com/blog/27/

Extracting a javascript file from webpack build

I am using webpack for a project where I need to have a javascript config file as part of the built files, but I cannot figure out how to do that.
So I need to have these files in the output:
index.html
app.js
config.js
I figure I need to either:
1) Copy the config.js file from the source folder to the build folder with CopyWebpackPlugin, or
2) Include the file in the compiled bundle and then extract it with ExtractTextWebpackPlugin.
I have tried dozens of different ways of configuring this, but when trying with the copy method, I get the file both inside the app.js bundle AND as a separate file. When I try with the extract method, I cannot seem to figure out how to extract javascript from the main bundle. The docs all seem to explain how to extract css.
How would I go about something like this?
You should be able to accomplish this by using multiple entry points.
https://webpack.js.org/concepts/entry-points/
entry: {
main: './path/to/file/app.js',
config: './path/to/file/config.js'
}
output: {
filename: 'output/path/[name].js'
}
A more complex option, which is typically used for vendor files, would be to use code-splitting.
https://webpack.js.org/guides/code-splitting/

Javascript project structure for dev and production using npm and grunt

I am trying to structure javascript files in a project. I have used NPM to manage the modules and planning to use Grunt to concatenate and compress the js and css files for deployment.
I am currently using the following structure
-[project root]
-- [node modules] :packages such as requirejs, jquery, semantic-ui etc using npm
--[war]
---[Dev]
----[css] multiple css files from modules (Question 2:?)
----[js] multiple js files from modeuls (Question 2:?)
- Gruntfile.js :for concatenate and compress
---[Production] -
----[css]:This is where the compressed and concatenated css files are kept
----[js] :This is where the compressed and concatenated js files are kept
Question 1: Is the above approach to structure the project correct ? Any other recommendations which allows to manage the packages, dev and production files.
Question 2: Can NPM or another tool allows me to pick up the js and css files from the [node modules] folder and place them to (dev>>css or dev>>js) folder ? If am doing this manually how do I track the versions ? Seems like I am missing something here, there must be a better solution.
Suggestions/recommendations/comments are much appreciated.
Thanks
The question is a bit too wide for SO format, but in general your structure is good. Instead of copying files from node_modules, you have your own JavaScript files under js and you import/require them to your own files.
//foo.js
//ES6 style imports
import {Foo as Bar} from "biz";
//Common JS style requires
var Bar = require("biz");
//AMD style requires
require(["biz"], function (Bar) {
If you want to use your node_modules in a browser, you'll want to bundle them using Browserify, Webpack, Rollup or similar. To automate this, you can easily use Grunt tasks such as grunt-browserify together with grunt-watch.
Same applies for your CSS files: You store your own files under css and if you need CSS files from node_modules you can import them to your own files: if you are using some preprocessor (such as SASS or LESS), the preprocessors usually inline your imports when building the .css-file. If you are just using plain .css files, see grunt-css-import for example.

Import less file in package

I've got a preamble.lessimport file with definitions of standard colors, sizes, mixins etc. that I import in all other .less files. So far, the file was placed in /client and I included it with
#import '/client/preamble.lessimport';
Worked as a charm.
Now, I'm moving all styles to a smart package to make them reusable. How do I include the preamble now?
I've tried putting it as preamble.lessimport in the main package dir and then including with both
#import '/preamble.lessimport';
and
#import 'preamble.lessimport';
Both result in the compile error:
While building package `theme`:
input: Less compiler error: '/preamble.lessimport' wasn't found
Placing the file in a subfolder didn't help. The file is added in package.js and I use less package in both client and server.
How can I properly import that file?
Edit:
I've worked around this issue by importing via relative path:
#import '../../../preamble.lessimport';
However I'm not happy with that solution as the package is on early stage and files inside tends to move a lot. Is there any absolute path I could use?
As of meteor 0.7 you no longer use the .lessimport extension. Your less files should have the .import.less extension.
Take a look at how the bootstrap3-less project imports bootstrap for best use examples.

Categories

Resources