Related
I'm getting a compilation error when trying to run nuxt with vuetify. It says that vuetify.css was not found with the dependency absolute path. I checked in buildDir/App.js and vuetify.css is the only dependency to reference a fullpath. Is there a reason to that ?
What do I miss ?
yarn dev
This dependency was not found: friendly-errors 10:34:11
friendly-errors 10:34:11
* .\full\path\to\myproject\src\node_modules\vuetify\dist\vuetify.css in ./myproject/prod/server/nuxt/App.js
friendly-errors 10:34:11
To install it, you can run: npm install --save .\full\path\to\myproject\src\node_modules\vuetify\dist\vuetify.css
buildDir/App.js
...
import '..\\..\\..\\src\\assets\\main.css'
import '..\\..\\..\\src\\assets\\variables.scss'
import '.\\full\\path\\to\\myproject\\src\\node_modules\\vuetify\\dist\\vuetify.css'
import _6f6c098b from '..\\..\\..\\src\\layouts\\default.vue'
...
package.json
"dependencies": {
"#nuxtjs/axios": "^5.9.2",
"#nuxtjs/firebase": "^4.1.0",
"firebase": "^7.10.0",
"lodash": "^4.17.15",
"nuxt": "^2.0.0",
"nuxt-i18n": "^6.5.0"
},
"devDependencies": {
"#babel/runtime-corejs3": "^7.8.7",
"#nuxtjs/dotenv": "^1.4.1",
"#nuxtjs/vuetify": "^1.11.0",
"#vue/test-utils": "^1.0.0-beta.27",
"babel-jest": "^24.1.0",
"core-js": "3",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.9.0",
"eslint-plugin-prettier": "^3.0.1",
"jest": "^24.9.0",
"prettier": "^1.16.4",
"vue-jest": "^4.0.0-0"
}
nuxt.config.js
import webpack from 'webpack'
require('dotenv').config({ path: '../.env' })
export default {
mode: 'universal',
server: {
host: process.env.HOST_NAME,
port: process.env.HOST_PORT
},
env: process.env,
head: {
titleTemplate: '%s - ' + process.env.npm_package_name,
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900' },
]
},
loading: { color: '#fff' },
css: [
'#/assets/main.css',
'#/assets/variables.scss'
],
plugins: [],
buildModules: [
['#nuxtjs/vuetify', { }],
['#nuxtjs/dotenv', { path: '../', filename: '.env' }]
],
modules: [],
vuetify: {
customVariables: ['~/assets/variables.scss'],
optionsPath: "./vuetify.options.js",
},
buildDir: "../prod/server/nuxt",
build: {
plugins: [
new webpack.ProvidePlugin({
'_': 'lodash'
})
],
extractCSS: true,
extend (config, ctx) {},
babel: {
presets({ isServer }) {
return [
[
require.resolve('#nuxt/babel-preset-app'),
{
buildTarget: isServer ? 'server' : 'client',
corejs: { version: 3 }
}
]
]
}
}
}
}
I started getting this error once I upgraded to Webpack and related dependencies to v4: [Vue warn]: Failed to mount component: template or render function not defined.
Here's the relevant snippets of my package.json and webpack.config.js before and after:
Before upgrade:
package.json
{
"dependencies": {
"vue": "^2.5.0",
"vue-template-compiler": "^2.5.0"
},
"devDependencies": {
"babel-core": "^6.9.0",
"babel-loader": "^6.2.4",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-es2015-block-scoping": "^6.26.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.9.0",
"babel-preset-es2015-without-strict": "^0.0.4",
"babel-preset-es2017": "^6.24.1",
"babel-preset-latest": "^6.24.1",
"css-loader": "^0.26.0",
"eslint": "^4.3.0",
"husky": "^0.14.3",
"lint-staged": "^4.0.2",
"resolve-url-loader": "^1.6.0",
"sass-loader": "^4.0.1",
"stats-webpack-plugin": "^0.2.1",
"style-loader": "^0.13.1",
"uglifyjs-webpack-plugin": "^1.1.6",
"vue-loader": "^12.1.0",
"webpack": "3.10.0",
"webpack-dev-server": "^2.3.0",
"webpack-monitor": "^1.0.13"
}
}
webpack.config.js
{
resolve: {
modules: [
path.join(__dirname, '..', 'webpack'),
'node_modules/'
],
alias: {
vue: process.env.NODE_ENV === 'production' ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js',
libs: 'libs/'
}
},
plugins: [
new StatsPlugin('manifest.json', {
chunkModules: false,
source: false,
chunks: false,
modules: false,
assets: true
})],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: ['es2015']
}
}
]
}, {
test: /\.vue$/,
exclude: /node_modules/,
use: [
{
loader: 'vue-loader'
}
]
},
{
test: /\.js$/,
include: [
path.resolve(process.cwd(), 'node_modules/')
],
use: [
{
loader: 'babel-loader',
options: {
plugins: ['transform-es2015-block-scoping'],
cacheDirectory: true
}
}
],
},
]
}
};
After upgrade:
package.json
{
"dependencies": {
"vue": "^2.5.13",
"vue-template-compiler": "^2.5.13"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.3",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.6.1",
"babel-preset-latest": "^6.24.1",
"css-loader": "^0.26.0",
"eslint": "^4.3.0",
"husky": "^0.14.3",
"lint-staged": "^4.0.2",
"resolve-url-loader": "^1.6.0",
"sass-loader": "^4.0.1",
"stats-webpack-plugin": "^0.2.1",
"style-loader": "^0.13.1",
"uglifyjs-webpack-plugin": "^1.1.6",
"vue-loader": "^14.1.1",
"webpack": "^4.0.1",
"webpack-cli": "^2.0.9",
"webpack-dev-server": "^3.0.0",
"webpack-monitor": "^1.0.13"
}
}
webpack.config.js
{
resolve: {
modules: [
path.join(__dirname, '..', 'webpack'),
'node_modules/'
],
alias: {
vue: process.env.NODE_ENV === 'production' ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js',
libs: 'libs/'
}
},
plugins: [
new StatsPlugin('manifest.json', {
chunkModules: false,
source: false,
chunks: false,
modules: false,
assets: true
})],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
]
}, {
test: /\.vue$/,
exclude: /node_modules/,
use: [
{
loader: 'vue-loader'
}
]
},
{
test: /\.js$/,
include: [
path.resolve(process.cwd(), 'node_modules/')
],
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
],
},
]
}
};
What is expected?
Vue components work without errors after upgrading
What is actually happening?
Most Vue components show an error and fail to load: [Vue warn]: Failed to mount component: template or render function not defined.
Figured this out (h/t #skribe). Basically I was declaring components like this:
Vue.component('thing', require('libs/components/thing.vue'));
I had to change that to:
Vue.component('thing', require('libs/components/thing.vue').default);
I'm building an app using webpack, react, babel, and Sass. I've been trying to get Sass working, but it's not playing ball. It's not throwing any errors, it just doesn't seem to be compiling properly, and when I examine the element in Dev Tools, it simply says "invalid property value" where I've referenced a variable. Is there something glaringly obvious I'm doing wrong?
My app.scss:
#import '../../../node_modules/normalize.css/normalize.css';
#import '../variables.scss';
/*
* Base styles
* ========================================================================== */
*,
*:after,
*:before {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
body {
text-align: center;
margin: 0;
}
p {
color: $blue;
}
My variables.scss:
/*
* Colors
* ========================================================================== */
$blue: #334c6a;
$yellow: #f6d463;
$white: #ffffff;
$black: #000000;
/*
* Typography
* ========================================================================== */
$font-family-base: 'Segoe UI', 'HelveticaNeue-Light', sans-serif;
/*
* Layout
* ========================================================================== */
$container-margin: 55px;
Webpack.config:
var path = require("path");
var webpack = require("webpack");
var autoprefixer = require('autoprefixer');
var precss = require('precss');
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/build/',
filename: "bundle.js"
},
resolve: {
extensions: ['*', '.js', '.jsx', '.png', '.json']
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.LoaderOptionsPlugin({
options: {
context: __dirname,
postcss: [
autoprefixer
]
}
})
],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader', 'babel-loader']
},
{
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'postcss-loader']
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
};
Package.json:
{
"name": "test",
"version": "1.0.0",
"description": "test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server"
},
"author": "test",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^6.7.7",
"babel-core": "^6.24.1",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.0",
"file-loader": "^0.11.1",
"node-sass": "^4.5.2",
"postcss": "^5.2.17",
"postcss-loader": "^1.3.3",
"precss": "^1.4.0",
"react-hot-loader": "^1.3.1",
"style-loader": "^0.16.1",
"webpack": "^2.3.3",
"webpack-dev-server": "^2.4.2"
},
"dependencies": {
"normalize.css": "^6.0.0",
"react": "^15.5.4",
"react-dom": "^15.5.4"
}
}
This config is working with webpack 2 and sass.
{
test: /\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
And then in the App.js file
import './app.scss'
The complete webpack.config
var path = require("path");
var webpack = require("webpack");
var autoprefixer = require('autoprefixer');
var precss = require('precss');
module.exports = {
context: path.resolve(__dirname, 'src'),
entry: [
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
'./index.js'
],
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/build',
filename: "bundle.js"
},
devServer: {
hot: true,
contentBase: path.resolve(__dirname, 'build'),
publicPath: '/',
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// new webpack.NoErrorsPlugin(), not needed any more
new webpack.LoaderOptionsPlugin({
options: {
context: __dirname,
postcss: [
autoprefixer
]
}
})
],
module: {
rules: [{
test: /\.js?$/,
exclude: /node_modules/,
loaders: ['babel-loader']
},
{
test: /\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader' , 'postcss-loader']
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
}
]
}
};
My scss files are not getting compiled. It doesn't understand what I do with my code. I want to be able to use Sass instead of CSS but I can't find the right way to compile Sass.
I am using the webpack template with Vue.js
My webpack config file looks like this:
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src'),
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.scss$/,
use: [ 'style-loader','css-loader','sass-loader' ],
loaders: ['style', 'css', 'sass']
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
One way of doing it is to have a single scss file as an entry. This is where all your different scss file gets imported. Something like this. Then you import that scss file in source code of your js entry file (in this case ./src/main.js). So when webpack reads your main.js it will see import './myscssfile.scss' and looks for a loader (or I think it does). Here is how I do my scss module in webpack2:
module: {
rules: [
// my js stuff
{ test: /\.js$/, enforce: 'pre', loader: 'eslint-loader', exclude: /node_modules/ },
// my scss stuff
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 2,
sourceMap: true,
localIdentName: '[local]___[hash:base64:5]'
}
},
{
loader: 'autoprefixer-loader',
options: {
browsers: 'last 2 version'
}
},
{
loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: true
}
}
]
}
]
}
I hope it works.
Just use <style lang="sass"></style in your component. Let me know if it helps.
Having the following webpack configuration for assets compiling I can't get autoprefixer to work. The extracted css does not get the needed prefixes.
var webpack = require('webpack'),
precss = require('precss'),
autoprefixer = require('autoprefixer'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path');
const sassLoaders = [
'css-loader!autoprefixer-loader?browsers=last 2 version',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname, '.')
]
const config = {
entry: {
//nsb: ['./js/nsb']
dashboard: ['./js/dashboard']
},
module: {
loaders: [
{
test: /\.sass$/,
loader: ExtractTextPlugin.extract('style-loader', sassLoaders.join('!'))
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass')
},
{
test: /\.docs\.css$/,
loader: "style-loader!css-loader!postcss-loader?pack=cleaner"
},
{
test: /\.css$/,
loader: "style-loader!css-loader!postcss-loader"
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
postcss: function () {
return {
defaults: [precss, autoprefixer],
cleaner: [autoprefixer({ browsers: [] })]
};
},
output: {
filename: '[name].js',
path: path.join(__dirname, './build'),
publicPath: '/bundles/dashboard/build/'
},
amd: {jQuery: true},
plugins: [
new ExtractTextPlugin('[name].css'),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
],
/* postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
*/
resolve: {
alias: {
jquery: 'node_modules/jquery/dist/jquery.js',
magnificPopup: 'node_modules/maginific-popup/dist/jquery.magnific-popup.js' //JQuery Plugin
},
modulesDirectories: ['./js', 'node_modules'],
extensions: ['', '.js', '.sass'],
root: [path.join(__dirname, './')]
}
}
module.exports = config;
The css-loader comes with it's own autoprefixer config you will need to disable this in order for your config to work. So wherever you have css-loader you need to do add to disable the css-loader autoprefixer.
css-loader?-autoprefixer
More info can found here & here
So your config will look like this
var webpack = require('webpack'),
precss = require('precss'),
autoprefixer = require('autoprefixer'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path');
const sassLoaders = [
'css-loader?-autoprefixer!autoprefixer-loader?browsers=last 2 version',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname, '.')
]
const config = {
entry: {
//nsb: ['./js/nsb']
dashboard: ['./js/dashboard']
},
module: {
loaders: [
{
test: /\.sass$/,
loader: ExtractTextPlugin.extract('style-loader', sassLoaders.join('!'))
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass')
},
{
test: /\.docs\.css$/,
loader: "style-loader!css-loader?-autoprefixer!postcss-loader?pack=cleaner"
},
{
test: /\.css$/,
loader: "style-loader!css-loader?-autoprefixer!postcss-loader"
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
postcss: function () {
return {
defaults: [precss, autoprefixer],
cleaner: [autoprefixer({ browsers: [] })]
};
},
output: {
filename: '[name].js',
path: path.join(__dirname, './build'),
publicPath: '/bundles/dashboard/build/'
},
amd: {jQuery: true},
plugins: [
new ExtractTextPlugin('[name].css'),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
],
/* postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
*/
resolve: {
alias: {
jquery: 'node_modules/jquery/dist/jquery.js',
magnificPopup: 'node_modules/maginific-popup/dist/jquery.magnific-popup.js' //JQuery Plugin
},
modulesDirectories: ['./js', 'node_modules'],
extensions: ['', '.js', '.sass'],
root: [path.join(__dirname, './')]
}
}
module.exports = config;
Also, I think you can remove the autoprefixer-loader that you have inside your sassLoaders since you are using PostCSS with autoprefixer.
You could try the following code, notice the addition of "?-autoprefixer" between css-loader and postcss-loader.
var webpack = require('webpack'),
precss = require('precss'),
autoprefixer = require('autoprefixer'),
ExtractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path');
const sassLoaders = [
'css-loader!autoprefixer-loader?browsers=last 2 version',
'postcss-loader',
'sass-loader?indentedSyntax=sass&includePaths[]=' + path.resolve(__dirname,
'.')
]
const config = {
entry: {
//nsb: ['./js/nsb']
dashboard: ['./js/dashboard']
},
module: {
loaders: [
{
test: /\.sass$/,
loader: ExtractTextPlugin.extract('style-loader', sassLoaders.join('!'))
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass')
},
{
test: /\.docs\.css$/,
loader: "style-loader!css-loader?-autoprefixer!postcss-loader?pack=cleaner"
},
{
test: /\.css$/,
loader: "style-loader!css-loader?-autoprefixer!postcss-loader"
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
postcss: function () {
return {
defaults: [precss, autoprefixer],
cleaner: [autoprefixer({ browsers: [] })]
};
},
output: {
filename: '[name].js',
path: path.join(__dirname, './build'),
publicPath: '/bundles/dashboard/build/'
},
amd: {jQuery: true},
plugins: [
new ExtractTextPlugin('[name].css'),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js', Infinity)
],
/* postcss: [
autoprefixer({
browsers: ['last 2 versions']
})
],
*/
resolve: {
alias: {
jquery: 'node_modules/jquery/dist/jquery.js',
magnificPopup: 'node_modules/maginific-popup/dist/jquery.magnific-popup.js' //JQuery Plugin
},
modulesDirectories: ['./js', 'node_modules'],
extensions: ['', '.js', '.sass'],
root: [path.join(__dirname, './')]
}
}
module.exports = config;
One more note: In my project's root directory I also have a postcss.config.js with the following content:
module.exports = {
parser: 'postcss-scss',
plugins: [
require('autoprefixer'),
]
}