Meteor packages with images - meteor

I want to create a theme package with css, js and images. The theme package looks like:
packages/
theme
css
theme.css
js
theme.js
img
logo.png
I can package css and js like so:
Package.onUse(function(api) {
var themeFiles = [
'theme/css/theme.css',
'theme/js/theme.js'
];
api.addFiles(themeFiles, 'client');
});
Do I need to package the images to use them? I tried to ref the logo png like this but it didn't work:
logo
How can non css or js files can be distributed and used as meteor packages?
Thanks

You need to declare package assets such as images using the regular api.addFiles method :
api.addFiles("img/logo.png","client",{
isAsset: true
});
isAsset is not mandatory here because we're adding an image, but note that if we wanted to add JS or CSS files as public staticly served files, we would have to specify this option to avoid Meteor bundling these files along with the concatenated/minified initial app JS/CSS.
Then you will be able to reference these assets using this type of path :
`/packages/package-author_package-name/img/logo.png`
Given that your package name is package-author:package-name.

You could also use api.addAssets(filenames, architecture) and access from client like /packages/username_package-name/file-name see https://docs.meteor.com/api/packagejs.html#PackageAPI-addAssets

Related

Vue-cli & webpack: dynamic import of css file from 3rd party packages, doesn't resolve css url paths correctly

I have a vue component which imports 3 different CSS files based on value of a prop. As you see, all of them are from 3rd party packages
if (!this.icon.toString().startsWith("fa")) {
import ("material-design-icons-iconfont/dist/material-design-icons.css");
} else if (this.icon.startsWith("mdi")) {
import("#fortawesome/fontawesome-free/css/all.min.css");
} else {
import("#mdi/font/css/materialdesignicons.min.css");
}
Build condition is:
build target is lib and build path is dist/src
css.extract is set to true in vue.config.js
all other webpack configs are the defaults by vue-cli and vue v2.6.14
all of these CSS files reference to some fonts within their package's build path using url(path) function. For example material-design-icons-iconfont have package structure like below:
In picture, material-design-icons.css file references to fonts inside ./fonts directory.
When I build my application, as it's expected, 3 different bundles will be created for each CSS file and all of them will be stored in dist/src/css/*. Also all fonts that these 3 CSS files are referencing will be stored in dist/src/fonts/*. So far So good!
The problem is webpack doesn't resolve/rewrite the paths specified in url() functions correctly and leaves them alone. So as I mentioned above for material-design-icons.css, it doesn't rewrite url() paths to ../fonts/* and leaves them as ./fonts/. So component loading fails cause CSS's fonts are not found in dist/src/css/fonts
I have tried some solutions found on the net, but none of them works, somehow all of them are based on local CSS files, not 3rd party files
What's the problem and how to fix it?
Regards

How to find css file of scss file in angular project

I have created the angular project in VS Code using the following command.
ng new my-app --style=scss
by following this github link
Now every style sheet that is being created using angular-cli is with extension of .scss instead of .css
Now there is a requirement to check that how Sass is being converted to css because I am new to Sass. I am facing some issues in designing thus it would be nice for me to look at css file.
I have searched in those folder where scss file exists but there I couldn't find css file. Please help
Update
Look at this picture, when I created the component using cli, it created .scss instead of css so I need to look for css file.
I've been able to find a way to view my compiled .scss files as a .css file.
Before I only saw the raw .scss files when inspecting from Chrome.
The trick was setting some flags in the angular.json file so it will tell webpack (what angular-cli uses to build the app) that I want the .scss files served as .css along with a sourcemap of the file:
./angular.json
{
...
"projects": {
"my-prject": { <-- or whatever your project is named
"architect": {
"configurations": {
"production": { // <-- production is default, you might be working w/ custom configurations [development, test, w/e]
...
"sourceMap": true, <-- will serve source maps w/ the file so you can view it in the browser easily
"extractCss": true, <-- actually serve the .css files and not the .scss files
...
}
}
}
}
}
}
Once that is updated, restart the dev server or rebuild your application
then you can go into chrome dev tools and look at find the styles.css file (or whatever you have the file name set to) and view it:
If you are working on local then:
local {
"sourceMap": true,
...
}
Sass in Angular 2 are always converted into Css in run time when you compile and build the project. However if you are using any other environment like Gulp tasks and watches, you can run 'sass --watch input.scss output.css'
As folks have already mentioned, the css is built at runtime. You can still set the result using inspect in chrome or firefox.
It's definitely a requirement to check the generated CSS when you find something wrong and Chrome Inspector can't help! So this is definitely a good question, which is why I'm here.
To summarize, #y_vyshnevska is right that "you may find your css inlined in script tags at the end of head", and he also gave an in-depth link: https://blog.angularindepth.com/this-is-how-angular-cli-webpack-delivers-your-css-styles-to-the-client-d4adf15c4975 on the topic. I put it here in case you neglect it.
It looks not possible to view compiled css files at a runtime.
However, you can do the following trick: angular applies components' styles using <style> attribute. Find the one you need in elements inspector (you can search there using ctrl (or cmd) + f.
After you've found the stylesheet you need, you'll see it's truncated. To see the entire content, click on the style element and select "Store as global variable". After that in console run
copy(Object.values(temp1.sheet.cssRules).map(r => r.cssText).join('\n'))
This will copy all css to your buffer

Minimizing Individual Assets with Webpack

I would like to optimize a wordpress website with webpack. The application is not a single page app, and each page requires their own styles, scripts, and images in the head. I would like to use webpack to minimize css, js, and images in place. I don't need a single bundle file.
In a folder with three css files, I would like to iterate through each of the files and minimize them.
css/
page.css ---> page.css(minimized)
header.css ---> header.css(minimized)
footer.css ---> footer.css(minimized)
I would like to do the same with js files and use an image optimizer for jpgs, png, ect. Can this be done with webpack? If so, how could this be done? I have read about multiple entry points but that does not seem to be what I need. Thanks!
No, multiple entry points will still only give one output. What you could do, is write a wrapping script which wraps your webpack.config.js and having the entry config variable set to be dynamic.
Pseudo-code:
import glob from 'glob'
import webpack from 'webpack'
import config from './webpack.config'
const files = glob.glob('**/my-entry-file.js');
files.forEach((file) => {
config.entry = file;
webpack(config);
});

how to stop meteor from auto merging my css files?

I have 2 html files linked to each other and have different css files for each of them, but meteor merges them automatically.
How do I stop this?
You cannot. Meteor merges CSS to optimize its network delivery.
If you want to choose the order your stylesheets have in the merged CSS you may need to :
- Use a language as SASS, LESS or Stylus which allow to generate css so you could do #import 'imports/ui/yourstylesheet.scss' to #import files in the order you want. Note that if you choose to use a language as SASS or LESS you need to put your sass/less files that you want to import into /imports so you manually import them (puting files anywhere else than in /imports makes your files automatically imported). And import these files via a SASS/LESS/stylus file in the /client folder.
OR
- Put your css in /client folder and understand the Meteor's rules to choose in which order your css get loaded :
The JavaScript and CSS files in an application are loaded according to
these rules:
Files in subdirectories are loaded before files in parent directories,
so that files in the deepest subdirectory are loaded first, and files
in the root directory are loaded last.
Within a directory, files are loaded in alphabetical order by
filename.
After sorting as described above, all files under directories named
lib are moved before everything else (preserving their order).
Finally, all files that match main.* are moved after everything else
(preserving their order).
OR
- You put your .css in the /imports directory (so Meteor doesn't import them automatically so you can choose in which order you load css files). And you import your css via a .js (javascript) file put into /client (as files into /client are loaded on your browser). In the .js file you do import '/imports/ui/mystylesheet.css' to import your css.
The cons of the three methods are respectively :
- You have to learn a language if you don't know any of these languages : stylus less or sass.
- Relying on complex rules to choose the order your css get loaded is probably not maintainable and oblige you to have specific names for your css
- css files loaded within a .js file are put in a <style> tag inside the DOM instead of being loaded in a separate .css file (which is not recommended). Besides the css loaded this way doesn't use the toolchain offered by Meteor plugins (compression of CSS, add pre-vendor prefixed to maximize the compatibility of your css and whatever the plugin you have offers you).
You can carefully change the order of load. Such as to make one override the other.
For example consider the following file structure
|-client
|-imports
|-ui
|-page1
|-page1.html
|-page1.js
|-page1.css
|-page2
|-page2.html
|-page2.js
|-page3.css
Here, page1.js will import page1.css and this css will be applied to the template in page1.html
Similarly, page2.js can import page2.css and the same will be applied when the page2.html is rendered.
You can add your css class to the template when calling the route if you are using the iron router.
Router.route('/addMemberProfile',{
onBeforeAction: function () {
$('body').addClass('your required class for this template');
this.next();
},

How to handle CSS with meteor?

I am building a test app to learn how to organize multiple files with METEOR.
I have a head.html and inside I have the following link to my custom CSS:
<!-- Custom CSS -->
<link type="text/css" rel="stylesheet" href="/stylesheets/globals/style.css"/>
Very normal, Yet I have trouble to make that working.
Here is my app directory:
-app folder
---client
-----head.html
-----index.html
-----stylesheets
-------globals
---------style.css
I know it seems to be a very basic question but I can not figure it out.
Basically you have 2 ways of inserting CSS in a Meteor project :
Using the Meteor build tool to automatically concatenate and minify all your CSS files living in the client/ directory : in this case you don't need to import your stylesheets using a link tag in the head. This is perfect for vital CSS files that your app should load when started.
Example : put your CSS file under client/stylesheets/globals/style.css and that's it, no need to import it, it's automatically injected in your project by Meteor.
Using the classic way of importing stylesheets in a web application : you can put your CSS files inside the public/ directory and they will be served by your app server. In this case the Meteor build process will be skipped so files won't be concatenated together nor minified. Use this method when you want to lazy load big CSS files only needed in a subpart of your app (for example admin section styling).
Example : put your minified CSS file under public/stylesheets/admin/style.css, and use something like iron:router to load the CSS file when hitting the admin route.
Router.route("/admin", {
// onRun hooks executed only once
onRun: function(){
// create a link taf holding a reference to our publicly served CSS file
var link=$("<link>",{
rel: "stylesheet",
href: "/stylesheets/admin/style.css"
});
// append to the head tag
$("head").append(link);
}
});

Resources