Unable to use material design icons in vuetify - javascript

I install icons css using npm install material-design-icons-iconfont and it is available in node modules. After i build, the below woff files available in dist
Material-design-icons.css
/* For IE6-8 */
src: local("Material Icons"), local("MaterialIcons-Regular"),
url("./fonts/MaterialIcons-Regular.woff2") format("woff2"),
url("./fonts/MaterialIcons-Regular.woff") format("woff"),
url("./fonts/MaterialIcons-Regular.ttf") format("truetype");
all the three woff files shows 404. I verified in dist folder, i can see all those files in static/fonts/.woff.
In browser console also `localhost:8000/static/fonts/.woff. All the file names and paths are correct, but still see 404 error in console.

Afetr NPM installation, why not follow the Vuetify documentation by importing it in your main.js or app.js file.
// main.js
import 'material-design-icons-iconfont/dist/material-design-icons.css'
// Ensure you are using css-loader
Vue.use(Vuetify, {
iconfont: 'md'
})
But the easiest way is just to include the CDN link:
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">

There are multiple material icon packages flying around. There are also multiple formats, SVGs and what not. It is easy to get confused. Assuming you have a standard vuetify configuration and your goal is to have a locally installed font because you don't like injecting foreign substance to your head, then following should work:
Eliminate the external library
First edit your public/index.html and comment out the #mdi import. This line also gives us a clue to which package vuetify is expecting.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#mdi/font#latest/css/materialdesignicons.min.css">
Install your local dependency
Then in your project folder, install the #mdi / font package.
yarn add #mdi/font
Import into Vue
Then, finally we need to get this newly download package into our application. You can import anywhere, but it's good practice to keep vuetify related things in the vuetify configuration file which is located at plugins/vuetify.js
import "#mdi/font/css/materialdesignicons.min.css";
Let Vuetify know all about it
and make sure to export material design as the preferred icon font for your vuetify project.
Inside plugins/vuetify.js
export default new Vuetify({
icons: {
iconFont: "md",
},
});
You might want need to rebuild your project. Have a great day.
P.S # points to your node_modules folder.

Have you checked you have css-loader in you webpack config?
module: {
loaders: [
{ test: /\.css$/, loader: "css-loader" }
]
}

Related

Is there a way to integrate stencil components into frameworks locally without publishing to NPM?

I am currently testing stencil js. For now I want to write stencil components and include them within a VUE/React project. The official website of stencil already shows how to integrate them within a framework (https://stenciljs.com/docs/overview). But they assume that your own stencil component library has already been published to npm.
Is there a way to integrate stencil components locally into a framework to test them without publishing them first?
Yes, you can use npm-link for that.
cd my-component-lib
npm link
cd ../my-app
npm link my-component-lib # or whatever you have named the project in package.json
If you have any problems with that (e. g. with paths not resolving properly), you can also try to pack your package and install the packed version instead, using npm-pack:
cd my-component-lib
npm pack
cd ../my-app
npm install ../my-component-lib/my-component-lib-1.0.0.tgz
Linking is preferable though because changes to your component library will be reflected immediately (after a rebuild), whereas with packing you'd have to re-pack and re-install it after every change to your lib.
Instead of publishing or packing your packages, you could utilize TypeScript's path mapping feature.
This allows you to write your import statements just as you would with a published package, but behind the scenes TypeScript maps the imports to their given source code location.
Here's an example of a tsconfig.json with path mapping added to the compiler options:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"ui-components": ["libs/ui-components"],
"ui-components/loader": ["libs/ui-components/dist/loader/index.cjs.js"],
"ui-components-react": ["generated/ui-components-react/src/components.ts"]
},
...
As you can see, it has 3 mappings: the path to the core Stencil components ui-components, the path to the generated React components which are exposed as ui-components-react, as well as the generated loader ui-components/loader which provides the bridge between the Custom elements and the React wrappers.
I created a full working example for Stencil Web Components with generated bindings and wrappers for React that comes without the need of publishing any package: Nx Stencil React.
Please note that this answer is based on #stencil/core 1.14.0 or below. Future versions may have a different approach on generating the framework integrations.
I've had quite a bit of trouble with this myself so will provide an answer specifically for Vue 3 as Stencil's Framework Integrations guide seems to refer only to Vue 2.
Starting Projects
Stencil Component
Following the Getting Started guide run npm init stencil. Choose the component option.
There was a bug in v2.7.0 so I update to v2.8.0 with npm i #stencil/core#latest --save-exact
Build the project with npm run build
Optional
By default, the stencil project configures multiple build targets, to make it easier to see what build files are being used you can edit the stencil config to only include the custom elements bundle:
\\ stencil.config.ts
outputTargets: [
{
type: 'dist-custom-elements-bundle',
},
{
type: 'dist',
esmLoaderPath: '../loader',
},
],
You also need the 'dist' type for the .d.ts typings file to be generated with your custom-elements (not sure why).
Vue 3 App
Using a globally installed Vue CLI #vue/cli#4.5.13 create a new Vue 3 default project.
Using Stencil in Vue 3
Install your stencil component project
npm install --save ../<path>/stencil-component as a dependency of your vue app.
Fixing NPM Module Resolution
Following the Vue CLI - Troubleshooting guide add a vue.config.js file to the root of your Vue 3 project with the line config.resolve.symlinks(false),
Skipping Component Resolution
In the same file we need to configure Using Custom Elements in View
\\ vue.config.js
module.exports = {
chainWebpack: (config) => {
config.resolve.symlinks(false),
config.module
.rule("vue")
.use("vue-loader")
.tap((options) => ({
...options,
compilerOptions: {
isCustomElement: (tag) => tag.includes("my-"),
},
}));
},
};
Framework Integration
Now we can declare the custom elements, but in the Vue 3 way
\\ main.js
import { createApp } from 'vue'
import App from './App.vue'
import { defineCustomElements } from "stencil-component";
defineCustomElements();
createApp(App).mount('#app');
You can now use your custom component as normal. Here's what my App.vue file looked like after hacking the example starter code:
<template>
<my-component first="Andy" middle="2K" last="11"></my-component>
</template>
<script>
import { MyComponent } from "stencil-component";
export default {
name: 'App',
components: {
MyComponent
}
}
</script>
Errors
No ESLint Config
No ESLint configuration found in /<path>/stencil-component/dist/custom-elements.
Fixed by telling webpack not to resolve symlinks in vue.config.js
Uncaught TypeError: class constructors must be invoked with 'new'
This error occurs in the browser after a successful compilation.
Resolved by telling webpack / vue not to resolve your custom components
Custom Component Not Visible
There are no errors and your component is showing in the DOM inspector but not appearing on the page.
You need to defineCustomElements() in main.js.
Component not found
I've had some variation of this error when trying to import and use my component but haven't been able to reproduce it just now. Doing all of the above and restarting the dev server works fine for me.
For local integration, you can reference the esm.js file inside www/build folder which can be used in the head tag of the Vue/React project.
For eg if you have the below 2 apps
stencil-components - stencil components
stencil-react - sample react app which will consume the components.
Once you run stencil-components by npm run start it will be hosted at 3333 (by default).
Including below line in head ofindex.html of stencil-react will integrate components with live reloading on change.
<script type="module" src="http://localhost:3333/build/stencil-components.esm.js"></script>

Using NPM packages client-side with nuxt

I'm very new to nuxt and javascript and I'm trying to figure out how to use my app's dependencies client-side. I have them listed in my nuxt.config.js and installed with npm. I also have a file in the /plugins directory that imports them (not sure if this is good or not). Here is where I run into trouble: I have two scripts located in my /static directory that need to take advantage of my npm packages. Putting an import statement in those scripts causes an error. Importing the packages in the script section of the page vue file also doesn't work. How can I use npm packages in scripts that are included in pages client-side?
Can you provide a more information, about which kind of error is happening and which kind of packages did you try to install?
In this example I am going to show you how I included in my nuxt project npm package vuelidate
after installing vuelidate:
add to nuxt.config.js
plugins: [
{ src: "~/plugins/vuelidate", mode: "client" },
],
create vuelidate.js file in my plugin folder (plugin/vuelidate.js)
import Vue from 'vue'
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate);
after that I can use vuelidate in my .vue components (no always necessary to import something because in our 2 stage Vue.use(Vuelidate) we already installed vuelidate globally)
<script>
import { required, minLength } from "vuelidate/lib/validators";
export default {
name: "OrderByLinkForm",
components: {},
...
};
</script>

bundling multiple js files

in react using webpack every js files is bundle into a single bundle.js , for my normal html , css, js application for example , i am having 6 libraries. for an example consider
i am using jquery and bootstrap min versions. so if i reference two files the request will be two. so how can i make it into a single file. So there will be a single request.
like when i checked the file size is about in kb's and the request is processed within less that 1 or 2 seconds , like the chrome dev tools shows the time for to load also it parrallely loads the two files.
But how can i bundle the two librarys using webpack and get a single file that i can refer in my application.
i am a beginner to webpack
You need to import them in your entry point file and Webpack will handle the bundling. As you have worked with React, I assume you have basic command line skills.
You can read the Getting Started guide which bundles Lodash like how you are trying to bundle jQuery and Bootstrap.
First of install, ensure that you are installing jQuery, Bootstrap, and any other libraries using npm (or yarn, if you prefer):
# Install Webpack as a dev dependency
npm install webpack webpack-cli --save-dev
# Install dependencies (I've added Popper.js as Bootstrap requires it)
npm install jquery bootstrap popper.js
Create a folder called src and a file inside there called index.js. This is your entry point and Webpack will look for this file unless configured differently. Import the libraries like this:
import $ from 'jquery'
import 'bootstrap'
// Do something with jQuery
$(document).ready(() => console.log('Hello world!'))
Then run Webpack using npx:
npx webpack
A file named main.js should be created in a folder called dist that contains the bundled code. This is your output file. You can use a <script> tag in your HTML file to load this JavaScript:
<!-- assuming your index.html is in the dist folder -->
<script src='main.js'></script>
Once you get here, you can explore more advanced things like importing Bootstrap components individually, minifying code, multiple bundles, transpiling TypeScript, etc.
You will likely need to add a Webpack configuration file very soon as there is only so much that can be done using zero-config mode.
Good practice is to keep two sepearate bundles for the application logic and external libraries and in webpack this can be achieved by the following code,
app.js - appliation index file,
vendors.js - import all external libraries in this file
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
To get a single file, import vendors.js file inside app.js file and give entry key in webpack as
entry: './src/app.js'
Let us assume that you have the files in src directory. You can merge multiple files by specifying them in webpack.config.js to have a single named file as an output. I hope this is what you are looking for.
const path = require('path');
module.exports = {
entry: {
'bundle.js': [
path.resolve(__dirname, 'src/file1.js'),
path.resolve(__dirname, 'src/file2.js')
]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
exclude: /node_modules/
}]
}
};
As above, the two files "file1.js" and "file2.js" will be combined into a single file "bundle.js" and stored in "dist" directory.
You can also exclude node_modules by specifying a rule in module object of webpack configuration.

Cannot resolve directory 'bootstrap'

I've downloaded an angular starter and I'm trying to install Bootstrap on it. They explain how to do that in the External Stylesheet section.
I've installed bootstrap:
npm i bootstrap --save
npm i bootstrap-sass --save
and then added in the top of styles.scss:
#import 'bootstrap/scss/bootstrap.scss';
But it's marked with red mentions:
Cannot resolve directory 'bootstrap'
Any help will be profoundly appreciated!
As previously mentioned, you need to add the tilde when you're importing inside your css.
#import 'bootstrap/scss/bootstrap.scss';
Second, the bootstrap css file is loading fonts along with the stylesheet, resulting in the error you're having because it's using relatives paths webpack doesn't know where to pickup.
To fix that, you could either change the path of the folder to the correct one like the following as seen from here:
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap";
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
And add the fonts loader to your webpack configuration:
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'url-loader',
}
But the easiest way for you to get around the problem would be to remove the style import you are doing, remove the bootstrap-sass dependency and use the cdn instead.
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
The advantage of doing this is that clients that have already downloaded bootstrap using this cdn will get the cached version. Since a lot of websites theses days use it, It's very likely they won't have to download it again, and it also saves you the trouble of hosting it or incorporating into your bundle.
Nothing exists at src/styles/bootstrap/scss/bootstrap.scss, so you can either manually copy/paste (or download) a bootstrap.scss file there OR just import bootstrap into your src/styles/styles.scss from your node_modules via:
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
You'll get font-related errors until you add in a line before that so your styles.scss reads:
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
#import "~bootstrap-sass/assets/stylesheets/bootstrap";
More: https://stackoverflow.com/a/35575175/3814251
In order to let sass-loader import a sass module from mode_modules folder, prepend the module path with a ~. Otherwise the provided path is resolved like a relative one:
#import "~bootstrap/scss/bootstrap.scss";
For more info check out sass-loader docs.

Importing CSS files in Isomorphic React Components

I have a React application with Components written in ES6 - transpiled via Babel and Webpack.
In some places I would like to include specific CSS files with specific Components, as suggested in react webpack cookbook
However, if in any Component file I require a static CSS asset, eg:
import '../assets/css/style.css';
Then the compilation fails with an error:
SyntaxError: <PROJECT>/assets/css/style.css: Unexpected character '#' (3:0)
at Parser.pp.raise (<PROJECT>\node_modules\babel-core\lib\acorn\src\location.js:73:13)
at Parser.pp.getTokenFromCode (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:423:8)
at Parser.pp.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:106:15)
at Parser.<anonymous> (<PROJECT>\node_modules\babel-core\node_modules\acorn-jsx\inject.js:650:22)
at Parser.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\plugins\flow.js:694:22)
at Parser.pp.nextToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:98:71)
at Object.parse (<PROJECT>\node_modules\babel-core\lib\acorn\src\index.js:105:5)
at exports.default (<PROJECT>\node_modules\babel-core\lib\babel\helpers\parse.js:47:19)
at File.parse (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:529:46)
at File.addCode (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:611:24)
It seems that if I try and require a CSS file in a Component file, then the Babel loader will interpret that as another source and try to transpile the CSS into Javascript.
Is this expected? Is there a way to achieve this - allowing transpiled files to explicitly reference static assets that are not to be transpiled?
I have specified loaders for both .js/jsx and CSS assets as follows:
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel'}
]
}
View the full webpack config file
FULL DETAILS BELOW:
webpack.common.js - A base webpack config I use, so I can share properties between dev and production.
Gruntfile.js - Gruntfile used for development. As you can see it requires the webpack config above and adds some development properties to it. Could this be causing the problem?
Html.jsx - My HTML jsx component that tries to import/require the CSS. This is an isomorphic app (using Fluxbile), hence needing to have the actual HTML as a rendered component. Using the require statement seen in this file, in any part of my application, gives the error described.
It seems to be something to do with grunt. If I just compile with webpack --config webpack.common.js then I get no errors.
Short answer: It's a node runtime error. Trying to load CSS on the server in isomorphic apps is not a good idea.
You can't require css in the component that you are rendering on the server. One way to deal with it is to check if it's a browser before requiring css.
if (process.env.BROWSER) {
require("./style.css");
}
In order to make it possible you should set process.env.BROWSER to false (or delete it) on the server
server.js
delete process.env.BROWSER;
...
// other server stuff
and set it to true for the browser. You do it with webpack's DefinePlugin in the config -
webpack.config.js
plugins: [
...
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
]
You can see this in action in gpbl's Isomorphic500 app.
If you're building an isomorphic app with ES6 and want to include CSS when rendering on the server (important so basic styles can be sent down to the client in the first HTTP response) check out the #withStyles ES7 decorator used in React Starter Kit.
This little beauty helps ensure users see your content with styles when the page is first rendered. Here's an example isomorphic app I'm building leveraging this technique. Just search the codebase for #withStyles to see how it's used. It goes a little something like this:
import React, { Component, PropTypes } from 'react';
import styles from './ScheduleList.css';
import withStyles from '../../decorators/withStyles';
#withStyles(styles)
class ScheduleList extends Component {
We had a similar problem with our isomorphic app (and a lot of other problems, you can find details here). As for the problem with CSS import, at first, we were using process.env.BROWSER. Later we've switched to babel-plugin-transform-require-ignore. It works perfectly with babel6.
All you need is to have the following section in your .babelrc
"env": {
"node": {
"plugins": [
[
"babel-plugin-transform-require-ignore", { "extensions": [".less", ".css"] }
]
]
}
}
After that run your app with BABEL_ENV='node'. Like that:
BABEL_ENV='node' node app.js.
Here is an example of how a production config can look like.
You can also try this
https://github.com/halt-hammerzeit/webpack-isomorphic-tools
or this
https://github.com/halt-hammerzeit/webpack-react-redux-isomorphic-render-example
I used this babel plugin with success to solve a similar issue with less, svg and images. But it should work with any non js assets.
It rewrites all assets imports into variables, so as long as you run the compiled code just on the server and have a bundle built with webpack for the client, it should be fine.
The only drawback is that it onlyworks with named imports, so you'll have to:
import styles from './styles.css';
in order to make it work.
Make sure you are using the loaders in your webpack config:
module: {
loaders: [
{ test: /\.jsx$/, exclude: /node_modules/, loader: "babel" },
{ test: /\.css$/, loader: "style!css" }
]
}
You probably have an error in your Webpack config where you're using the babel-loader for all files, and not just .js files. You want to use a css loader for .css files.
But you shouldn't use import for loading any other module than Javascript modules, because once imports are implemented in browsers, you will only be able to import Javascript files. Use require instead in cases where you need Webpack specific functionality.
ORIGINAL POST
Webpack uses require and Babel lets you use import from ES6 which mostly do the same thing (and Babel transpiles the import to a require statement), but they are not interchangable. Webpacks require function lets you specify more than just a module name, it lets you specify loaders as well, which you cannot do with ES6 imports. So if you want to load a CSS file, you should use require instead of import.
The reason is that Babel is just a transpiler for what's coming in ES6, and ES6 will not allow you to import CSS files. So Babel won't allow you to do that either.
I've finally realised that this error is not originating at the compile stage, but rather at runtime. Because this is an ismorphic app, the components and any dependencies they have will first be parsed on the server (ie, in node). It is this that is causing the error.
Thanks for all the suggestions, I will post more if/when I figure out how to have per-component stylesheets in an isomorphic application.
I also met the same problem when I want to do the server-side render.
So I write a postcss plugin, postcss-hash-classname.
You don't require css directly.
You require your css classname js file.
Because all you require is js file, you can do the server-side render as usual.
Besides, this plugin also use your classname and file path to generate unique hash to solve css scope problem.
You can try it!
Solved With This...
https://github.com/michalkvasnicak/babel-plugin-css-modules-transform
$ npm install --save-dev babel-plugin-css-modules-transform
Include plugin in .babelrc
{
"plugins": ["css-modules-transform"]
}
And Import Css..... Like This Anywhere You Want
const styles = require('./test.css');
OR
import css from './styles.css'
Also See This... Apart From Css Files........................................................ .
https://www.npmjs.com/package/babel-plugin-transform-assets

Categories