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);
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 }
}
]
]
}
}
}
}
New to webpack,and, learning curve is fun. But my need is simply do the following (which I'm doing using bash today)
node-sass ./src/styles/default.scss > ./dist/assets/default.css
I don't need to include it in the html.
I don't want to include the css into javascript file.
Just plain conversion from scss to css.
Nvm, got the following working for me:
webpack.config.js
var path = require('path');
const HtmpWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: { main: './src/index.js' },
output: {
path: path.resolve(__dirname, 'dist/assets'),
filename: 'default.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: { loader: 'babel-loader' }
}, {
test: /\.(png|svg|jpe?g|gif)$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
}, {
test: /\.scss$/,
use: [
{ loader: "style-loader" },
{ loader: MiniCssExtractPlugin.loader },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
}
]
},
plugins: [
new HtmpWebPackPlugin({
path: __dirname + '/dist/assets',
filename: 'default.html',
template: 'src/index.html',
inject: false,
hash: false
}),
new MiniCssExtractPlugin({
filename: 'default.css',
outputPath: 'dist/assets'
})
]
}
package.json
"scripts": {
"build": "rm -rf ./dist && webpack --mode production"
},
"devDependencies": {
"#babel/core": "^7.5.5",
"#babel/preset-env": "^7.5.5",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"file-loader": "^4.2.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.8.0"
}
I can't import background image through scss file in my react project using webpack. I followed all the recent advice on stackexchange but to no avail. I get this error message when I try to import images through either scss or css files:
Module not found: Error: Can't resolve 'marker.svg'
in the scss file
.marker {
background-image: url('./marker.svg');
scss config in webpack
{
test: /\.s[ac]ss$/,
use: [{
loader: 'style-loader',
options: { sourceMap: IS_DEV }
}, {
loader: 'css-loader',
options: {
localIdentName: '[hash:base64:5]',
modules: true,
sourceMap: IS_DEV
}
}, {
loader: 'postcss-loader',
options: { sourceMap: IS_DEV }
}, {
loader: 'sass-loader',
options: {
sourceMap: IS_DEV,
}
}]
},
image config in webpack
{
test: /\.(svg|png|jpg)$/,
use: {
loader: 'url-loader',
loader: 'svg-url-loader',
loader: 'file-loader',
loader: 'resolve-url-loader',
},
},
devserver config
devServer: {
historyApiFallback: true,
hot: true,
contentBase: dest,
compress: true,
port: 9000,
publicPath: 'http://localhost:9000/dest',
},
Is it the devserver? css-module? sourceMap? I have trouble importing image files in css as well. Please help
If you are using css-loader ^3.0.0 you should set url: false (marked with "---->"):
...
test: /\.(scss|sass)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader', options: {
-----> url: false,
importLoaders: 2,
modules: {
mode: 'local',
localIdentName: isProduction ? '[hash:base64:5]' : '[local]_[hash:base64:5]'
},
},
},
{ loader: 'postcss-loader' },
{ loader: 'sass-loader', options: {
includePaths: ['./src']
}
},
],
})
},
{
test: /\.(svg|png)$/,
use: {
loader: 'url-loader', options: {
name: 'assets/[hash].[ext]',
limit: 5000,
},
}
},
...
use resolve-url-loader before sass-loader like so
{
test: /\.s[ac]ss$/,
use: [{
loader: 'style-loader',
options: { sourceMap: IS_DEV }
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
},
{ loader: 'resolve-url-loader', }
{
loader: 'sass-loader',
options: {
sourceMap: IS_DEV,
}
}]
},
My Angular application is working properly, but I am keep getting Karma error when I run ng test command. I have attached app component, spec, module and html along with package.json file. Error looks like this:
Failed: No provider for ChildrenOutletContexts!
Error: No provider for ChildrenOutletContexts!
at injectionError (http://localhost:9876/_karma_webpack_/vendor.bundle.js:39523:90)
at noProviderError (http://localhost:9876/_karma_webpack_/vendor.bundle.js:39561:12)
at ReflectiveInjector_.webpackJsonp.../../../core/#angular/core.es5.js.ReflectiveInjector_._throwOrNull (http://localhost:9876/_karma_webpack_/vendor.bundle.js:41003:19)
at ReflectiveInjector_.webpackJsonp.../../../core/#angular/core.es5.js.ReflectiveInjector_._getByKeyDefault (http://localhost:9876/_karma_webpack_/vendor.bundle.js:41042:25)
at ReflectiveInjector_.webpackJsonp.../../../core/#angular/core.es5.js.ReflectiveInjector_._getByKey (http://localhost:9876/_karma_webpack_/vendor.bundle.js:40974:25)
at ReflectiveInjector_.webpackJsonp.../../../core/#angular/core.es5.js.ReflectiveInjector_.get (http://localhost:9876/_karma_webpack_/vendor.bundle.js:40843:21)
at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/vendor.bundle.js:47827:25)
at NgModuleRef_.webpackJsonp.../../../core/#angular/core.es5.js.NgModuleRef_.get (http://localhost:9876/_karma_webpack_/vendor.bundle.js:48909:16)
at resolveDep (http://localhost:9876/_karma_webpack_/vendor.bundle.js:49412:45)
at createClass (http://localhost:9876/_karma_webpack_/vendor.bundle.js:49276:32)
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
title = 'app';
}
app.component.html
Dashboard
User
<router-outlet></router-outlet>
app.component.spec.ts
import { TestBed, async } from '#angular/core/testing';
import { RouterModule, Routes } from '#angular/router';
import { FormsModule } from '#angular/forms';
import { APP_BASE_HREF } from '#angular/common';
import { AppComponent } from './app.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
describe('AppComponent', () => {
const routes: Routes = [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: DashboardComponent,
},
{
path: 'user',
loadChildren: 'app/modules/user/user.module#UserModule'
}
];
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterModule,
FormsModule
],
declarations: [
AppComponent,
DashboardComponent
],
providers: [
{ provide: APP_BASE_HREF, useClass: routes }
]
}).compileComponents();
}));
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it('should have as title app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
}));
});
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { RouterModule, Routes } from '#angular/router';
import { AppComponent } from './app.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
const routes: Routes = [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: DashboardComponent,
},
{
path: 'user',
loadChildren: 'app/modules/user/user.module#UserModule'
}
];
#NgModule({
declarations: [
AppComponent,
DashboardComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent],
exports: [RouterModule]
})
export class AppModule { }
package.json
...
"dependencies": {
"#angular/animations": "^4.0.0",
"#angular/common": "^4.0.0",
"#angular/compiler": "^4.0.0",
"#angular/core": "^4.0.0",
"#angular/forms": "^4.0.0",
"#angular/http": "^4.0.0",
"#angular/platform-browser": "^4.0.0",
"#angular/platform-browser-dynamic": "^4.0.0",
"#angular/router": "^4.0.0",
"core-js": "^2.4.1",
"rxjs": "^5.1.0",
"zone.js": "0.8.12"
},
"devDependencies": {
"#angular/cli": "1.2.1",
"#angular/compiler-cli": "^4.0.0",
"#angular/language-service": "^4.0.0",
"#types/jasmine": "~2.5.53",
"#types/jasminewd2": "~2.0.2",
"#types/node": "~6.0.60",
"codelyzer": "~3.0.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.0.4",
"tslint": "~5.3.2",
"typescript": "~2.3.3",
....
Based on the clue provided by #John, I imported RouterTestingModule instead of importing RouterModule and APP_BASE_HREF. So, the following modification in app.component.spec.ts worked!
import { TestBed, async } from '#angular/core/testing';
import { FormsModule } from '#angular/forms';
import { RouterTestingModule } from '#angular/router/testing';
import { AppComponent } from './app.component';
import { DashboardComponent } from './modules/dashboard/dashboard.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
FormsModule
],
declarations: [
AppComponent,
DashboardComponent
]
}).compileComponents();
}));
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',
}
]
}
};