In my webpack project, I want to inject styles as a <style> tag into the page, using JavaScript, rather than referencing an external file via a <link> tag. I am using style-loader for styles currently, and it outputs a bunch of link tags in the head.
Rather than this:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/things">
<link rel="stylesheet" type="text/css" href="/things">
<link rel="stylesheet" type="text/css" href="/things">
</head>
<body>
I want this:
<html>
<head>
</head>
<style>
/* things here */
</style>
<body>
Is there any way of doing this? I had a read of the documentation but it only mentions building CSS output files, not outputting to a style tag in this way.
Reasons:
I am publishing a module to be included via NPM/Bower, and I would rather keep the build as a single package, rather than having to revert to
It is faster. There is a lot of literature around minimising the number of requests, including from webpack: https://github.com/christianalfoni/react-webpack-cookbook/wiki/Inlining-images
It turns out that adding the loaders to the imports manually does the trick. Removing this loaders definition from the webpack config:
module: {
loaders: [{
test: /\.scss$/,
loaders: ['style!css!sass!']
}]
}
and adding manually to each style import:
import React from 'react';
import 'style!css!sass!./fieldList.scss'; // -> this line
class FieldList extends React.Component
This causes the styles to be injected in my preferred way.
Try to use second entry point for styles.
All styles will be loaded first and then added to <style> tags in <head> section.
webpack.config.js:
export default {
entry: {
app: ['./app'],
styles: ['./styles']
},
loaders: [{
test: /\.(scss|css)$/,
loaders: [
'style',
'css',
'autoprefixer?browsers=last 3 versions',
'sass'
]
}]
}
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="styles.js"/>
</head>
<body>
<script src="app.js"/>
</body>
</html>
Related
I'm building a javascript app with vite.
I want to use tailwind for quick styling but setting it up in my project is something I struggle with all the time.
From the experience I've set it up but it's not working and I don't know why..
I suspect it is because of my change of root directory in the vite project.
My homepage:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link href="/src/style/output.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hermes</title>
</head>
<body>
<h1>My homepage</h1>
Test
<div id="app" class="h-14 bg-gradient-to-r from-purple-500 to-pink-500">h</div>
<script type="module" src="../main.ts"></script>
</body>
</html>
My tailwind config:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/views/*.html"],
theme: {
extend: {},
},
plugins: [],
}
My main.css (input file by tailwind)
#tailwind base;
#tailwind components;
#tailwind utilities;
The output file which is linked in the html, is full of the basic style rest by taildwind
This is my folder structure:
I believe you need to create the postcss.config.cjs file manually with this content:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
The tailwind docs make it sound as though npx tailwindcss init -p will automatically create postcss.config.cjs but that didn't happen for me.
Install tailwindcss and its peer dependencies via npm, and then run the init command to generate both tailwind.config.cjs and postcss.config.cjs.
Once I added postcss.config.cjs and restarted the dev server the styles were applied.
I am working on a Firestore, Vue project and having an issue with building my project. Running the non-built files on a local server works just fine and after running the build command, the files all appear to be correct. However, after uploading the files to Firebase (or creating a local server using the built files using the firebase serve command), it just shows a blank page. So I inspected the files and the css and js files are the exact same as the HTML file.
I know that this guy had the same issue, Upload to Firebase Hosting not working correctly, but I have gone through every file I feel like may be the culprit and still cannot find where the issue is — although that may just be due to my lack of knowledge in how webpack works. I think it may be some misconfiguration in the vue.config.js file but not sure. I would appreciate any help in getting my project hosted! Thanks!
Here is my file structure:
- dist
- src
- assets
- css
- img
- js
- favicon.ico
- index.html
- public
- index.html
- src
- App.vue
- main.ts
- .firebaserc
- firebase.json
- package.json
- vue.config.js
Compiled index.html
<!DOCTYPE html>
<html lang=en>
<head>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=msapplication-tap-highlight content=no>
<meta name=description content="Steel Tech of the Ozarks designs & manufactures pre-engineered metal buildings, driven by an intentional, no-compromise passion for excellence.">
<meta name=keywords content=steel,building,metal,structural,design,manufacture>
<title>Company Name</title>
<link rel="shortcut icon" href=../src/assets/favicon/favicon.ico>
<meta name=theme-color content=#6e8995>
<link as=style href=/dist/src/assets/css/app.64e0dd85.css rel=preload>
<link as=style href=/dist/src/assets/css/chunk-vendors.9e123139.css rel=preload>
<link as=script href=/dist/src/assets/js/app.00d6273a.js rel=preload>
<link as=script href=/dist/src/assets/js/chunk-vendors.90527da6.js rel=preload>
<link href=/dist/src/assets/css/chunk-vendors.9e123139.css rel=stylesheet>
<link href=/dist/src/assets/css/app.64e0dd85.css rel=stylesheet>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id=app>
<script src=/dist/src/assets/js/chunk-vendors.90527da6.js></script>
<script src=/dist/src/assets/js/app.00d6273a.js></script>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="msapplication-tap-highlight" content="no">
<title>Company Name</title>
<link rel="apple-touch-icon" sizes="180x180" href="../src/assets/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="../src/assets/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="../src/assets/favicon/favicon-16x16.png">
<link rel="manifest" href="../src/assets/favicon/site.webmanifest">
<link rel="mask-icon" href="../src/assets/favicon/safari-pinned-tab.svg" color="#ff6600">
<link rel="shortcut icon" href="../src/assets/favicon/favicon.ico">
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<!-- Built files will be auto injected -->
<div id="app"/>
</body>
</html>
App.vue
<template>
<v-app>
<router-view/>
</v-app>
</template>
main.ts
import Vue from 'vue'
import App from './App.vue'
import router from '#/router'
import store from '#/store'
import '#/plugins/vuetify'
Vue.config.productionTip = false
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app')
.firebaserc
{
"projects": {
"default": "schedule-maxx"
}
}
firebase.json
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
vue.config.js
module.exports = {
runtimeCompiler: true,
lintOnSave: true,
productionSourceMap: false,
outputDir: 'dist',
assetsDir: 'src/assets',
baseUrl: process.env.NODE_ENV === 'production' ? '/dist/' : '/',
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8081',
changeOrigin: true,
pathRewrite: {
'^/api': '/api/v1'
}
}
}
}
}
With regards to your file structure, in particular:
dist
public
index.html
and to the fact that you rewrite to /index.html (cf. firebase.json file)
I think that your firebase.json file should start as follows. (However, since you don't show what's in the dist directory I am not 100% sure!):
{
"hosting": {
"public": "public",
....
}
}
and the static directory generated by webpack should also be deployed under the public directory. It is most probably under the dist directory for the moment.
It looks like I just had my vue.config.js file configured incorrectly. I changed the baseUrl field from '/dist/' to '.' and the file paths in the compiled files were correct.
I'm working on a visual studio 2017 template project of .net core 2 + Angular SPA template.
I'm having a problem that some of html elements appear twice, 1 appearance with css applied and the other isn't.
when i deploy the app it looks like in the image below.
As you can see the place holder 'Choose a number' and the dropdown arrow appear twice.
When i press the upper arrow 2 dropdowns are opened with the options.
If i press the downer arrow only the downer dropdown opened.
the whole div should be coloured in blue but only the "not in place" elements are blue.
the component is a prime-NG component but it occurs with other NPM packages (kendo UI for example).
I assume that it might be related to the order of css files and NPM loading during bootstrap but I can't find the place
index.cshtml:
#{
ViewData["Title"] = "Home Page";
}
<app>Loading...</app>
<script src="~/dist/vendor.js" asp-append-version="true"></script>
#section scripts {
<script src="~/dist/main-client.js" asp-append-version="true"></script>
}
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - GSM.WebMonitorTool</title>
<base href="~/" />
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
</head>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
choose-number.component.html:
<div class="query-context-all">
<div class="dropdown">
<p-dropdown [options]="numbers" [(ngModel)]="chosenNumber" placeholder="Choose a number"></p-dropdown>
</div>
</div>
choose-number.component.ts :
import { Component } from '#angular/core';
import { SelectItem } from 'primeng/api';
#Component({
selector: 'context-input',
templateUrl: './context-input.component.html',
styleUrls: ['./context-input.component.css']
})
export class ContextInputComponent {
chosenNumber: string;
numbers: SelectItem[];
constructor() {
this.numbers = [
{ label: "1", value: "1" },
{ label: "2", value: "2" },
{ label: "3", value: "3" }];
}
}
So thanks to John Velasquez, I understood that i had to add primeNG's css file to webpack. Actually each shared components or fonts npm may require this addition. As a beginner with Angular i didn't know they must be added explicitly so I add here my steps that solved it, hoping it will save some time for others :)
steps:
adding the css file to webpack.config.vendor.vs - add the line 'primeng/resources/primeng.css' to nonTreeShakableModules array
update the rules of shared config, a few lines down, to { test: /\.(png|woff|woff2|eot|ttf|svg|jpe?g|gif)(\?|$)/, use: 'url-loader?limit=100000' }
run webpack --config webpack.config.vendor.js
from cmd/powershell, when path is the project folder.
I am following this tutorial. I could manage to browserify the bootstrap JS files, but I was wondering how can I add the bootstrap css to my config. I know that files are in node_modules folder, but how can I add them to the build workflow I already have?
gulpfile.js
...
gulp.task('sass', function() {
return gulp.src('./sass/style.sass')
.pipe(sass.sync().on('error', sass.logError))
.pipe(gulp.dest('./dist/css'));
})
gulp.task('browserify', function() {
// Grabs the app.js file
return browserify('./app/app.js')
// bundles it and creates a file called main.js
.bundle()
.pipe(source('bundle.js'))
// saves it the public/js/ directory
.pipe(gulp.dest('./dist/js/'));
})
...
app.js:
require('angular')
require('bootstrap')
var app = angular.module('app', []);
index.html:
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>My App</title>
<script src="/js/bundle.js"></script>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div style="height: 100%;" ui-view></div>
</body>
</html>
I have done my research with grunt-injector. However, I have not found anything explains simply enough the process of injecting some file to another by grunt-injector.
My index.html header:
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>SmartHome</title>
<meta name="description" content=""/>
<meta name="author" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- build:css(client) styles/global.css -->
<!-- bower:css -->
<link rel="stylesheet" href="/bower_components/normalize.css/normalize.css" />
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="/bower_components/nouislider/distribute/nouislider.min.css" />
<!-- endbower -->
<!-- endbuild -->
Everytime I run grunt serve, it would delete the
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
I have no idea why. My bower.json has included bootstrap ~3.3.4 as a dependency. I've tried numerous methods with bower install --dev etc... But no luck to get this link back.
So I think my last resort would be to use the grunt-injector function. Can anyone gives me a hint with the syntax needed ? My files structure:
/client/
---bower_components/
(somemore folders)
---bootstrap.css
index.html
For this task you can use: https://github.com/taptapship/wiredep
Example:
wiredep: {
task: {
// Point to the files that should be updated when
// you run `grunt wiredep`
src: [
'src/main/resources/view.html'
],
options: {
// See wiredep's configuration documentation for the options
// you may pass:
// https://github.com/taptapship/wiredep#configuration
}
}
}
injector: {
options: {
// Task-specific options go here.
},
bower_dependencies: {
files: {
'index.html': ['bower.json'],
}
}
}