Sorry I'm quite new to Nuxt & Webpack. I have a Nuxt project in which everything works fine running yarn dev. But when I build using yarn build -> yarn generate, the .css files I reference in the node_modules directory (dropzone.css, flatpickr.css etc) are never included and break the site. I've tried everything but can't figure out what I'm doing wrong. Can someone point me in the right direction? Currently running Nuxt v2.11.0 with Tailwind.css. This is my nuxt.config.js file which is mostly boilerplate -
require('dotenv').config()
export default {
env: {
baseUrl: process.env.BASE_URL || '/',
apiUrl: process.env.API_URL
},
mode: 'universal',
css: [
'#/assets/css/tailwind.css',
'#/assets/fonts/caslongraphique/webfont.css',
'#/assets/fonts/turbinadobolddry/font.css',
{ src: 'nuxt-dropzone/dropzone.css', lang: 'css' },
{ src: 'vue-agile/dist/VueAgile.css', lang: 'css' },
{ src: 'flatpickr/dist/flatpickr.css', lang: 'css' },
{ src: 'flatpickr/dist/themes/airbnb.css', lang: 'css' }
],
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: '~plugins/helpers' },
{ src: '~plugins/vue-moment' },
{ src: '~plugins/vue-agile', mode: 'client' },
{ src: '~plugins/eventBus', mode: 'client' },
{ src: '~plugins/axios', mode: 'client' },
{ src: '~plugins/vuex-persist', mode: 'client' }
],
buildModules: [
// Doc: https://github.com/nuxt-community/nuxt-tailwindcss
'#nuxtjs/tailwindcss',
],
modules: [
'#nuxtjs/axios',
'#nuxtjs/dotenv',
// 'nuxt-client-init-module'
],
build: {
/*
** You can extend webpack config here
*/
extend (config, ctx) {
},
postcss: {
plugins: {
// Disable a plugin by passing false as value
'postcss-url': false,
'postcss-nested': {},
'autoprefixer': true
},
preset: {
// Change the postcss-preset-env settings
autoprefixer: {
grid: true
}
}
},
}
}
It's pretty hard to answer this without having the full project to build and run. I assume you're not using a separate webpack config file when building for production, otherwise you would have added that to the question. You seem to be using the correct syntax in the config file, so I'm guessing your css file paths are not quite right. They kinda look like the old way of doing things, you may want to confirm that they're not out of date. This old-ish github issue goes through the various things you could try, on of them being let nuxt find the "compiled" version of the css automatically for you like this:
css: [
'nuxt-dropzone',
...etc
],
Try removing all of the 3rd party css files and add them back one at a time, after the previous one works.
This example is from the official docs:
export default {
css: [
// Load a Node.js module directly (here it's a Sass file)
'bulma',
// CSS file in the project
'#/assets/css/main.css',
// SCSS file in the project
'#/assets/css/main.scss'
]
}
Related
I'm building a chrome extension using Vite as my build tool. The main problem is during minification and mangling there are a lot of global variables created. After injecting my script to the page they conflict with already defined variables on window object.
I imagine the perfect solution would be to have my entire script wrapped in IIFE. I tried using esbuild.format = 'iife'. The resulting build is in fact wrapped in IIFE, however all the imports are not inlined. Instead resulting script is like 15 lines long with a bunch of require statements, which obviously does not work in the browser.
This is my config file:
export default defineConfig({
plugins: [
vue(),
],
esbuild: {
format: 'iife',
},
build: {
emptyOutDir: false,
rollupOptions: {
input: resolve(__dirname, './src/web/index.ts'),
output: {
dir: resolve(__dirname, './dist'),
entryFileNames: 'web.js',
assetFileNames: 'style.css',
},
},
},
resolve: {
alias: {
'#': resolve(__dirname, './src'),
},
},
});
I'm currently using this hack so to say to wrap my build in IIFE (for this I removed the esbuild.format option).
Hey I am doing the exact same thing! And I also noticed the unminified variables and functions can clash with random code in a webpage.
From what I researched myself on this topic, you shouldn't change esbuild build options with Vite as that will prevent Rollup from transforming the output. Instead, you should use format: 'iife' in the rollupOptions of your vite.config. However, in my case (and yours I believe), I have to output multiple bundles since the extension code can't share modules amongst each other. Which will crash when you set the format to 'iife' due to:
Invalid value for option "output.inlineDynamicImports" - multiple inputs are not supported when "output.inlineDynamicImports" is true.
The only solution in my case seems to be to either use multiple vite.configs (I already have two) for each of my bundle with single input entry point and format as 'iife'. Or, as you did, just write the self-invoking function yourself with some hacky script. Seems though there aren't any perfect solutions as of now.
EDIT: Okay, got it working. This is my vite.config.ts (the project):
import { defineConfig } from 'vite'
import { svelte } from '#sveltejs/vite-plugin-svelte'
import tsconfigPaths from 'vite-tsconfig-paths'
import path from 'path'
/** #type {import('vite').UserConfig} */
export default defineConfig({
plugins: [svelte({}), tsconfigPaths()],
build: {
minify: false,
rollupOptions: {
output: {
chunkFileNames: '[name].js',
entryFileNames: '[name].js'
},
input: {
inject: path.resolve('./src/inject.ts'),
proxy: path.resolve('./src/proxy.ts'),
'pop-up': path.resolve('./pop-up.html')
},
plugins: [
{
name: 'wrap-in-iife',
generateBundle(outputOptions, bundle) {
Object.keys(bundle).forEach((fileName) => {
const file = bundle[fileName]
if (fileName.slice(-3) === '.js' && 'code' in file) {
file.code = `(() => {\n${file.code}})()`
}
})
}
}
]
}
}
})
Okay, I made it working with this config:
export default defineConfig({
plugins: [
vue(),
],
build: {
emptyOutDir: false,
rollupOptions: {
input: resolve(__dirname, './src/web/index.ts'),
output: {
format: 'iife',
dir: resolve(__dirname, './dist'),
entryFileNames: 'web.js',
assetFileNames: 'style.css',
},
},
},
resolve: {
alias: {
'#': resolve(__dirname, './src'),
},
},
});
They key part is format: 'iife' inside build.rollupOptions.output.
While building the gatsby project, I faced this kind of error.
yarn develop
ERROR #98123 WEBPACK
Generating development JavaScript bundle failed
Cannot find module 'sanitize.css/page.css'
Require stack:
- D:\UpworkJobs\Nate\dci-gatsby-importexport\node_modules\postcss-normalize\dist\index.cjs.js
File: src\css\preview.css
failed Building development bundle - 366.725s
Here is a screenshot of the error log.
These kinds of errors occur even if I removed all CSS codes from the style files.
It seems importing CSS files is not working. If I didn't import the CSS files, the errors go away.
Here are all codes of gatsby-config.js
let systemvars = false;
if (process.env.NODE_ENV === "production") {
systemvars = true;
}
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
systemvars
});
// Gatsby automatically sets NODE_ENV to `development` or `production` when running `gatsby develop` or `gatsby build`, respectively.
// Thus make sure you have .env.development or .env.production setup (unless your CI/build env vars are already set globally)
const AliasConfig = require("./alias.config.js");
module.exports = {
siteMetadata: {
title: `DCI DigiGuide Print`,
description: `DCI DigiGuide Printable Version`,
author: `#designbycosmic`,
siteUrl: process.env.SITE_URL,
},
plugins: [
//
// * App Functionality Plugins
//
// eslint plugin
{
resolve: "gatsby-plugin-eslint",
options: {
test: /\.js$|\.jsx$/,
exclude: /(node_modules|.cache|public)/,
stages: ["develop"],
options: {
maxWarnings: undefined,
emitWarning: true,
failOnError: false,
failOnWarning: false,
},
},
},
// allows content to be placed in head
`gatsby-plugin-react-helmet`,
// adds web manifest for some pwa functionality
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-dci-digiguide-print`,
short_name: `DigiGuidePrint`,
start_url: `/`,
background_color: `#222c47`,
theme_color: `#222c47`,
display: `minimal-ui`,
icon: `./src/images/favicon.png`, // This path is relative to the root of the site.
},
},
// allow alias imports
{
resolve: "gatsby-plugin-alias-imports",
options: {
alias: AliasConfig.map,
extensions: AliasConfig.extensions,
},
},
// inline svgs instead of converting them to base64
{
resolve: "gatsby-plugin-react-svg",
options: {
rule: {
include: /svg/,
},
},
},
`gatsby-plugin-postcss`,
`gatsby-plugin-material-ui`,
// Craft CMS configuration
{
resolve: `gatsby-source-graphql`,
options: {
url: process.env.CRAFT_API_URL,
typeName: "Craft",
fieldName: "craft",
headers: {
Authorization: `bearer ${process.env.CRAFT_API_TOKEN}`,
},
},
},
// Get build date
{
resolve: `gatsby-plugin-build-date`,
options: {
formatAsDateString: false,
},
},
],
};
Help me to solve this problem.
In my case I was able to solve by adding the following configuration in package.json.
"resolutions": {
"sanitize.css": "12.0.1"
},
Finally, this problem has been solved.
Using yarn instead of using npm solved the problem.
Remove node_modules and yarn install
After that, the problem has gone away.
Thank you.
I have a Gruntfile configured to, among other things, transpile an Express app to ES5 using Babel.
This is the configuration I have:
babel: {
es6: {
files: [
{
expand: true,
src: ['server/**/*.{js,json}'],
dest: 'output/',
ext: '.js'
}
]
}
},
This works pretty well. Most of my files are transpiled. The one issue that I run into is that the way my app is structured, the files aren't necessarily ending with just the .js extension. For example, I have in my transaction folder:
index.js
transaction.model.js
transaction.controller.js
transaction.model.spec.js
Therefore, in a hail mary I added the following to my configuration, to no avail.
babel: {
es6: {
files: [
{
expand: true,
src: ['server/**/*.{controller,model,transaction,js,json}'],
dest: 'output/',
ext: '.js'
}
]
}
},
How can I transpile these files with these 'custom' extensions?
Try doing this :
babel: {
es6: {
files: [
{
expand: true,
src: ['server/**/*.js'],
dest: 'output/',
ext: '.js'
}
]
}
}
or if for some reason it does not work try this
babel: {
es6: {
files: [
{
expand: true,
src: ['server/**/*.controller.js'], // just add the ext plus the .js
dest: 'output/',
ext: '.js'
}
]
}
}
My application is MEAN stack style. I would like to generate a package including all Nodejs and AngularJs files, so I could just unzip the package and run in other environments.
I use grunt-contrib-compress to compress and generate a zip file. Everything works well, but there are many development node modules are included, such as grunt*. All I need is the runtime node modules which are defined in the package.json. It will dramatically reduce the package size.
I could include the node modules one by one, but is there a good way only include runtime modules while packaging?
OK, I found a solution, which load the package.json and map the runtime dependencies into target folders.
compress: {
main: {
options: {
archive: 'myapp.zip'
},
files: [
{src: ['dist/**','app/**','config/**','server.js'],dest:'.'},
{src: Object.keys(require('./package.json').dependencies).map(function(module){
return "node_modules/" +module+"/**"
}),dest:'.'},
]
}
}
I had exactly the same question today, and after asking and coming up with a very similar solution, I have found your question. Here is my, similar but slightly different approach:
function getDependencies(pkg) {
return Object.keys(pkg.dependencies).map(function(val) { return val + '/**'; });
}
module.exports = function(grunt) {
var pkg = grunt.file.readJSON('package.json');
var config = {
pkg: pkg,
clean: ["public/"],
compress: {
validate: {
options: {
archive: 'public/Lambda.zip'
},
files: [
{ expand: true, cwd: 'src/', src: ['**'], dest: '/' },
{ expand: true, cwd: 'node_modules/', src: getDependencies(pkg), dest: '/node_modules' }
]
}
}
};
grunt.initConfig(config);
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.registerTask('build', ['clean', 'compress']);
}
For a single page app that I'm working on, I have the following structure:
dist
css
js
lib
partials
index.html
src
css
js
lib
views
partials
index.jade
Directory dist will be used by the express server to serve the project. I have trivial grunt tasks (using grunt-contrib-clean, grunt-contrib-copy) for cleaning dist and copying src/css, src/js, src/lib to dist.
The problem lies with src/views. This directory contains jade files which need to be compiled to html files. After compilation I want them in dist (index.html in the dist root, partials as subdir).
At the moment I am using the grunt-contrib-jade task to compile and copy the jade files. I want to copy them to dist, since I don't want to add the compiled html files to source control. But now this is not really workable, since you have to specify every jade file (now there are only a few, but that will grow):
jade: {
compile: {
options: {
pretty: true
},
files: {
// TODO make one line
'dist/index.html': ['src/views/index.jade'],
'dist/partials/banner.html': ['src/views/partials/banner.jade'],
'dist/partials/dashboard.html': ['src/views/partials/dashboard.jade'],
'dist/partials/navbar.html': ['src/views/partials/navbar.jade'],
'dist/partials/transfer.html': ['src/views/partials/transfer.jade']
}
}
},
Is there any way to use the grunt-contrib-jade task (or another one) with a directory filter? Like this:
jade: {
compile: {
options: {
pretty: true
},
dir: {
'dist': ['src/views']
}
}
}
Little clarification from Grunt wiki - expand mapping:
grunt.file.expandMapping(patterns, dest [, options])
Note that while this method may be used to programmatically generate a files array for a multi task, the declarative syntax for doing this described in the "Building the files object dynamically" section of the Configuring tasks guide is preferred.
Assuming the above, configuration will look like this:
files: [ {
expand: true,
src: "**/*.jade",
dest: "dist/",
cwd: "src/views",
ext: '.html'
} ];
Same result with declarative configuration.
I ended up upgrading to grunt 0.4 (which causes some other problems, but that I'll be able to handle).
With grunt version 0.4 it is possible to use grunt.file.expandMapping:
jade: {
compile: {
options: {
pretty: true
},
files: grunt.file.expandMapping(['**/*.jade'], 'dist/', {
cwd: 'src/views',
rename: function(destBase, destPath) {
return destBase + destPath.replace(/\.jade$/, '.html');
}
})
}
},
If you want to change only the extension of the files from .jade to .html, another option would be using the flatten and ext parameters like so:
jade: {
compile: {
options: {
data: { debug: false, title: 'My awesome application' }
},
files: grunt.file.expandMapping(['**/*.jade'], '<%= yeoman.dist %>/views', {
cwd: '<%= yeoman.app %>/views',
flatten: true,
ext: '.html'
})
}
}
Or even better (as explained here):
jade: {
compile: {
options: {
data: { debug: false, title: 'My awesome application' },
pretty: true
},
files: [
{
expand: true,
cwd: '<%= yeoman.app %>/views',
src: ['**/*.jade'],
dest: '<%= yeoman.dist %>/views',
ext: '.html'
}
]}
}
Thanks.