vue.runtime.esm-browser.js does not render Vue 3 components - vue.js

I created a vue 3 project using Vue cli. I am using a webpack config to manage my build. When I point my vue bundle to vue.runtime.esm-browser.js, then I get a warning in browser console. "[Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Use "vue.esm-browser.js" instead."
When I checked the docs, it was mentioned as "vue-loader" plugin converts the html template to render functions. Looks like I am missing something which is needed to webpack.
Entry file : main.js
import { createApp } from "vue";
import corecomponentA from "../core/components/corecomponentA.vue";
createApp({
components: {
"core-component-a": corecomponentA,
},
}).mount("#app");
Webpack.config.js
var path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { VueLoaderPlugin } = require("vue-loader");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
const WebpackBar = require("webpackbar");
module.exports = (env, options) => {
const devMode = options.mode != "production";
return {
entry: {
"vue-bundle-store": "./src/entry/main.js",
},
output: {
path: path.resolve(
__dirname,
"./../ui.clientlibs/src/js/"
),
filename: "[name].js",
chunkFilename: "[name].js",
publicPath: process.env.BASE_URL,
},
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: "/node_modules/",
query: {
presets: ["#babel/preset-env"],
},
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: { babelrc: true },
},
{
loader: "ts-loader",
options: { appendTsSuffixTo: [/\.vue$/] },
},
],
},
],
},
stats: {
colors: true,
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendor-bundle",
chunks: "all",
},
},
},
minimizer: !devMode
? [
new UglifyJsPlugin({
sourceMap: false,
uglifyOptions: {
chunkFilter: (chunk) => {
if (chunk.name === "vendor-bundle") {
return false;
}
return true;
},
compress: {
drop_console: true,
},
mangle: {
reserved: ["vueIns", "args", "el"],
},
},
}),
]
: [],
},
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
new WebpackBar(),
new BundleAnalyzerPlugin({
analyzerPort: 4000,
openAnalyzer: false,
analyzerMode: "static",
}),
] ,
resolve: {
extensions: [".ts", ".js", ".vue", ".json"],
alias: {
vue: devMode ? "vue/dist/vue.runtime.esm-browser.js" : "vue/dist/vue.runtime.esm-browser.prod.js"
}
}
};
};
coreComponentA.vue
<script lang="ts">
import { h, ref, reactive } from "vue";
export default {
setup() {
const str = ref("Core component B");
const object = reactive({ foo: "bar" });
return () => h("div", [str.value, object.foo]);
}
};
</script>
package.json
{
"name": "vue3.test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint",
"analyze-bundle": "webpack-bundle-analyzer stats.json",
"bundle": "webpack --mode=production --env.production --config webpack.config.js",
"bundle-dev": "webpack --mode=development --env.production=false --config webpack.config.js",
"stats": "webpack --mode=production --env.production --config webpack.config.js --profile --json > stats.json"
},
"dependencies": {
"vue": "^3.0.2"
},
"devDependencies": {
"#types/jest": "^24.0.19",
"#typescript-eslint/eslint-plugin": "^2.33.0",
"#typescript-eslint/parser": "^2.33.0",
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-plugin-typescript": "~4.5.0",
"#vue/cli-plugin-unit-jest": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/compiler-sfc": "^3.0.2",
"#vue/eslint-config-prettier": "^6.0.0",
"#vue/eslint-config-typescript": "^5.0.2",
"#vue/test-utils": "^2.0.0-0",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.6.5",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"html-webpack-plugin": "^3.2.0",
"prettier": "^1.19.1",
"typescript": "~3.9.3",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-jest": "^5.0.0-0",
"vue-loader": "^16.0.0-beta.8",
"webpack-cli": "^3.3.10",
"webpackbar": "^4.0.0"
}
}
babel.config.js
module.exports = {
ignore: [/\/core-js/],
presets: [
[
"#babel/preset-env",
{ modules: false, useBuiltIns: "usage", corejs: "3.6.5" },
],
],
overrides: [
{
test: "./node_modules",
sourceType: "unambiguous",
},
],
};
Usage of my component in a html file
<div id="app">
<core-component-a></core-component-a>
</div>
The component is not rendered in browser. Instead the below message is displayed.
VM211871:1 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Use "vue.esm-browser.js" instead.
at <App>

vue-loader converts the html template to render function only in SFC's (Sinle File Components) - .vue files (as you can tell from vue rule in Webpack config) - and only templates provided in <template></template> block of SFC
But you have a template in your HTML file - content of <div id="app"> is essentially Vue template. Runtime + Compiler vs. Runtime-only
Docs vue.esm-bundler.js: includes the runtime compiler. Use this if you are using a bundler but still want runtime template compilation (e.g. in-DOM templates or templates via inline JavaScript strings - component template option).
Also if you using Webpack, you should use "bundler" version of Vue
Webpack.config.js
alias: {
vue: "vue/dist/vue.esm-bundler.js"
}
...you don't need to switch minified/dev bundle because Webpack will (when configured correctly) optimize Vue code same way as your own code..
Also, pay attention to this sentence in the docs: Leaves prod/dev branches with process.env.NODE_ENV guards (must be replaced by bundler)
NODE_ENV is conventionally used to define the environment type and is used by Vue to decide what code to include...
Note
I don't really understand why are You using your own Webpack config for project created with Vue CLI when whole point of Vue CLI is to manage webpack config for you and offers plenty of options to customize it...doesn't make any sense

If you are using Vite, add the alias 'vue': 'vue/dist/vue.esm-bundler' to vite.config.js
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler',
},
}
})

you just have to replace on Webpack.config.js
alias: {
vue: devMode ? "vue/dist/vue.runtime.esm-browser.js" : "vue/dist/vue.runtime.esm-browser.prod.js"
}
With
vue: "vue/dist/vue.esm-bundler.js"
This works for me.

Related

Why is Vue undefined in my webpack-bundled app after trying to import it as a client-side library

I have been having an issue for 2 days and finally isolated it. Importing Vue and VueRouter gives me undefined in my frontend code. This is because the output from webpack, using the externals property to load client-side libraries, checks for module.__esModule when you import an externally loaded library, and if true then it returns module.default. In this case Vue.__esModule and VueRouter.__esModule are true while Vue.default and VueRouter.default are undefined. I'm not even sure who to file a bug with, or whether there is something I can add to webpack.config.js to make this work as before. It could be Vue for including __esModule on their global builds. Or it could be something in the internals of webpack.
Here is a section of my package.json
"devDependencies": {
"#babel/core": "^7.17.0",
"#babel/preset-env": "^7.16.11",
"#vue/compiler-sfc": "^3.2.30",
"babel-loader": "^8.2.3",
"css-loader": "^6.6.0",
"mini-css-extract-plugin": "^2.5.3",
"node-sass": "^7.0.1",
"sass-loader": "^12.4.0",
"vue-loader": "^17.0.0",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"vue": "^3.2.29"
}
And webpack.config.js
const VueLoader = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'production',
stats: 'errors-warnings',
entry: [
'./src/app.js',
],
output: {
filename: 'compiled.js',
path: __dirname + '/js',
},
optimization: {
minimize: true,
},
performance: {
hints: 'warning',
maxEntrypointSize: 250000, // JS output 250 kB
maxAssetSize: 250000, // CSS output 250 kB
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.m?js$/,
resolve: {
fullySpecified: false,
},
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {targets: '>1%'}],
],
},
},
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader, // add support for `import 'file.scss';` in JS
{
loader: 'css-loader',
options: {
url: false, // whether to resolve urls; leave urls in the code as written
},
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [
//__dirname + '/bower_components/bootstrap-sass/assets/stylesheets',
],
},
},
},
],
},
],
},
plugins: [
new VueLoader.VueLoaderPlugin(),
new MiniCssExtractPlugin({
// Output destination for compiled CSS
filename: '../css/compiled.css',
}),
],
};
And index.html loads Vue, VueRouter, Vuex, and then my bundled webapp:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.29/vue.runtime.global.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.2/vuex.global.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.12/vue-router.global.js"></script>
<script>console.log('healthcheck', Vue, Vuex, VueRouter);</script>
<script src="/js/compiled.js"></script>
Then in my frontend code, bundled with webpack:
import Vue from "vue";
import Vuex from "vuex";
import VueRouter from "vue-router";
console.log('client', Vue, Vuex, VueRouter);
Logs healthcheck {...} {...} {...} in the HTML and then the compiled app logs client undefined, {...}, undefined (Vuex is defined because Vuex.__esModule is undefined)
Any ideas what to do?
Answered here https://github.com/vuejs/core/issues/5380
Vue 3 only supports named imports, like import {createApp} from 'vue';

Vue 3 vendor bundle is bloated with #babel/parser/lib when vue.esm-bundler.js is used in webpack

I created a Vue 3 project and using webpack for bundling the package. Since I have in-DOM templates, I cannot go with the default #runtime-dom. So I have aliased Vue to point to vue.esm-bundler.js.
The issue I am facing is that, when I take a prod build, my vendor bundle is bloated with #babel/parser/lib.
Sample project to reproduce this issue is available here
Steps to follow:
npm install
npm run bundle
Open dist folder and see the Webpack bundle analyser report.
For ease of config, pasting the configs below.
webpack.config.js
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
const { VueLoaderPlugin } = require("vue-loader");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = (env, options) => {
const devMode = options.mode != "production";
return {
context: path.resolve(__dirname, "src"),
entry: {
"vue-bundle": "./entry/main.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
chunkFilename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/],
use: {
loader: "babel-loader",
options: {
presets: [
[
"#babel/preset-env",
{
targets: [">25%"],
debug: true,
corejs: "3.6.5",
useBuiltIns: false,
},
],
],
},
},
},
{
test: /\.vue$/,
use: "vue-loader",
},
],
},
plugins: [
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: "static",
reportFilename: "webpack_bundle_analyser_report.html",
defaultSizes: "gzip",
}),
],
optimization: {
mangleWasmImports: true,
removeAvailableModules: true,
sideEffects: true,
minimize: devMode ? false : true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
exclude: /\/node-modules/,
parallel: 4,
extractComments: false,
}),
],
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor-bundle",
chunks: "all",
},
},
},
},
devtool: devMode ? "eval-cheap-source-map" : false,
resolve: {
extensions: [".ts", ".js", ".vue", ".json"],
alias: {
vue: "vue/dist/vue.esm-bundler.js"
},
},
};
};
package.json
{
"name": "testPro",
"version": "1.0.0",
"private": true,
"scripts": {
"bundle": "webpack --mode=production --config webpack.config.js",
"bundle-dev": "webpack --mode=development --config webpack.config.js"
},
"devDependencies": {
"#babel/core": "^7.12.3",
"#babel/preset-env": "^7.12.1",
"#babel/preset-typescript": "^7.12.1",
"#vue/compiler-sfc": "^3.0.2",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.6.5",
"regenerator-runtime": "^0.13.7",
"terser-webpack-plugin": "^5.0.3",
"vue-loader": "^16.0.0-beta.4",
"webpack": "^5.3.0",
"webpack-bundle-analyzer": "^3.9.0",
"webpack-cli": "^4.1.0"
},
"dependencies": {
"vue": "^3.0.2"
}
}
Entry file main.js
import { createApp } from 'vue';
import App from '../App.vue';
createApp(App).mount('#app');
Not able to get what I am missing.
I strongly believe it is a bug in Vue 3 so I submitted a bug report - you can track it here
...I reproduced it myself using Vue CLI just to eliminate the chance the problem is in your Webpack config
You have 2 options to workaround this issue:
If you don't need to release right now, just work on your project and wait for a fix (I'm pretty sure it will be fixed - Vue builds for a browser which include compiler does not depend on #babel/parser so it's clear Vue don't need it to work correctly inside browser)
Don't use in-DOM templates and template option (string templates) - put everything in .vue files, <template></template> blocks - Runtime + Compiler vs. Runtime-only. Then you don't need a build with compiler...
EDIT: removed the part about missing process.env.NODE_ENV as --mode param to Webpack CLI does exactly that...

How to use sass in VUE application?

I am developing my first application in VUE
I have created a styles file at the root of the project and another with the fonts I want to use globally.
I'm trying to modify the styles of the components to be able to declare "" and thus be able to use these styles globally.
Following the official documentation and articles on the subject I do not see the solution to a bug that launches the console
"ERROR in ./node_modules/css-loader?sourceMap!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-7ba5bd90","scoped":false,"hasInlineConfig":false}!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue"
here is my vue.config.js
module.exports = {
css: {
loaderOptions: {
sass: {
prependData: `#import "#/styles/_variables.scss";`
}
}
},
}
and here my webpack.config.js
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
prependData:
`#import "#/styles/_variables.scss";`
}
}
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
// prependData:
// `#import "#/styles/_variables.scss";`
resources: [
path.resolve(__dirname, '../src/styles/_variables.scss')
]
}
}
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
and here my App.vue
<template>
<div id="app">
<div class="container">
<ciev-app-header />
<router-view></router-view>
<hr>
<ciev-app-footer></ciev-app-footer>
</div>
</div>
</template>
<script>
import Header from './components/Shared/Header';
import Footer from './components/Shared/Footer.vue';
export default {
name: 'app',
components:{
'ciev-app-header': Header,
'ciev-app-footer': Footer
},
created () {
this.$store.dispatch('tryAutoLogin')
}
}
</script>
<style lang="scss">
#font-face {
font-family: 'RalewayRegular';
src: local('RalewayRegular'),
url(./fonts/Raleway-Regular.ttf) format('truetype');
font-style: normal;
}
body, html {
margin: 0;
font-family: 'RalewayRegular', sans-serif;
}
</style>
Someone who can tell me what I'm doing wrong.
Thank you in advance for your time and help.
my package.json
{
"name": "vue-cli",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "Miguel Alvarez Gomez <miguel.alvarez#softtek.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"axios": "^0.19.2",
"style-resources-loader": "^1.3.3",
"vue": "^2.5.11",
"vue-router": "^3.3.4",
"vuex": "^3.5.1"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"node-sass": "^4.14.1",
"sass-loader": "^9.0.3",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}
You can use style-resources-loader plugin like this in vue.config.js file
vue.config.js
const path = require('path');
module.exports = {
...
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
// load which style file you want to import globally
patterns: [path.resolve(__dirname, './src/styles/_variables.scss')],
},
}
};
Edit: if this doesn't work, add this to your webpack.config module.rules array. It will tell webpack to use sass loader for your .scss files
{
test: /\/.scss$/,
loaders: ['style', 'css', 'sass']
}
After a lot of searching and trying different solutions I have found this article and following it step by step has worked perfect for me.
Only by installing the file-loader and adding the highlighted fields in the article to my webpack I have solved the problem.
I leave you the link in case someone is in the same situation.
https://chriscourses.com/blog/loading-fonts-webpack
Thank you for your help.

vue.js - dynamic imports results in error: Support for the experimental syntax 'dynamicImport' isn't currently enabled

I'm learning Vue.js with Webpack for the first time today and trying to get a router working with lazy/dynamic imports.
I want to use lazy/dynamic imports because I am rebuilding my content management system which has many, many pages that may or may not be used during the user's session, so loading the modules they need dynamically, when they need them, makes more sense with regards to my application.
My very basic router currently looks like this:
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
function loadView(view) {
return () => import(/* webpackChunkName: "view-[request]" */ `#/views/${view}.vue`);
}
export default new Router({
routes: [
{
path: "/",
name: "dashboard",
component: loadView("Dashboard")
},
{
path: "/login",
name: "login",
component: loadView("Login")
}
]
});
However, I run into the following compilation error:
ERROR in ./src/router/index.js Module build failed (from
./node_modules/babel-loader/lib/index.js): SyntaxError:
...../src/router/index.js: Support for the experimental syntax
'dynamicImport' isn't currently enabled
With the additional note:
Add #babel/plugin-syntax-dynamic-import to the
'plugins' section of your Babel config to enable parsing.
And shows me which line is the problem, which is quite obvious anyway:
return () => import(/*..........
^
I recognise this error from when I was playing with Webpack on its own a few months ago, so I knew I had to install the dynamic import plugin to make this work.
This is what I installed:
npm install babel-plugin-syntax-dynamic-import
And I made this plugin available in my babel.rc configuration file and ran npm run dev to recompile everything:
{
"presets": [
[
"#babel/env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}
]
],
"plugins": ["#babel/plugin-syntax-dynamic-import"]
}
But I'm still getting the error and I still can't use dynamic importing features! Am I doing something wrong? Has anybody else had trouble with getting dynamic imports to work?
My webpack.config file:
'use strict';
const webpack = require('webpack');
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
mode: 'development',
entry: [
'./src/app.js'
],
devServer: {
hot: true,
watchOptions: {
poll: true
}
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
{
test: /\.js$/,
use: 'babel-loader'
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
outputStyle: 'compressed',
data: `
#import "./src/assets/scss/_variables.scss";
#import "./src/assets/scss/_mixins.scss";
`
}
}
]
}
]
},
resolve: {
alias: {
"#": path.resolve(__dirname, './src'),
"Components": path.resolve(__dirname, './src/components/')
}
},
optimization: {
minimizer: [new UglifyJsPlugin()],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
})
]
}
My package.json file:
{
"name": "manage_v2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config build/webpack.config.dev.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.18.0",
"vue": "^2.5.22",
"vue-router": "^3.0.2",
"vuex": "^3.1.0"
},
"devDependencies": {
"#babel/core": "^7.2.2",
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"#babel/preset-env": "^7.3.1",
"babel-loader": "^8.0.5",
"babel-plugin-dynamic-import-webpack": "^1.1.0",
"css-loader": "^2.1.0",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.11.0",
"sass-loader": "^7.1.0",
"uglifyjs-webpack-plugin": "^2.1.1",
"vue-loader": "^15.6.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.22",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
}
}
I fixed the problem myself after many hours of frustration. I still don't know why the method that's used in the Babel, Webpack and Vue documentation doesn't work but I did get this working:
I first removed the plugin declaration from babel.rc file and then added an option to the babel loader in webpack.config file:
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
plugins: [
"#babel/plugin-syntax-dynamic-import"
]
}
}
}
I hope this helps others.
You have the wrong plugin assignment:
"plugins": ["#babel/plugin-syntax-dynamic-import"]
Would be the correct format for that plugin.

Load bootstrap with webpack for vue

How can I get bootstrap working and loaded with webpack for a vue project?
I have been trying to use this: https://www.npmjs.com/package/bootstrap-sass-webpack
I added the loaders to my webpack.config.js and installed bootstrap-sass-webpack. I get the following error when trying to build:
ERROR in ./~/bootstrap-sass-webpack/index.js
Module not found: Error: Cannot resolve module 'sass' in /Users/joebob/Desktop/vue-webpack-starter/node_modules/bootstrap-sass-webpack
# ./~/bootstrap-sass-webpack/index.js 1:0-76
webpack.config.js
module.exports = {
entry: './src/main.js',
output: {
path: './dist',
publicPath: 'dist/',
filename: 'build.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /\.vue$/,
loader: 'vue'
},
{ test: /\.woff$/, loader: "url-loader?limit=10000&minetype=application/font-woff" },
{ test: /\.ttf$/, loader: "file-loader" },
{ test: /\.eot$/, loader: "file-loader" },
{ test: /\.svg$/, loader: "file-loader" }
]
},
vue: {
loaders: {
js: 'babel'
}
}
}
package.json
{
"name": "vue-webpack-starter",
"version": "1.0.0",
"dependencies": {
"bootstrap-sass-webpack": "0.0.3",
"vue": "^1.0.16",
"vue-router": "^0.7.11"
},
"devDependencies": {
"babel-core": "^6.1.2",
"babel-loader": "^6.1.0",
"babel-plugin-transform-runtime": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"babel-preset-stage-0": "^6.1.2",
"babel-runtime": "^5.8.0",
"css-loader": "^0.23.0",
"file-loader": "^0.8.5",
"style-loader": "^0.13.0",
"url-loader": "^0.5.7",
"vue-hot-reload-api": "^1.2.0",
"vue-html-loader": "^1.0.0",
"vue-loader": "^7.3.0",
"webpack": "^1.12.2"
}
}
main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './app.vue'
import Home from './home.vue'
import Items from './items.vue'
require("bootstrap-sass-webpack")
Vue.use(VueRouter)
var router = new VueRouter()
router.map({
'/': {
name: 'home',
component: Home
},
'/items': {
name: 'items',
component: Items
}
})
router.start(App, '#app')
Adding sass-loader fixed this error. Am now getting:
ERROR in ./~/bootstrap-sass-webpack/~/css-loader!./~/sass-loader!./~/bootstrap-sass-webpack/bootstrap-sass-styles.loader.js!./~/bootstrap-sass-webpack/bootstrap-sass.config.js
Module build failed:
scripts: {
^
Invalid CSS after "#icon-font-path": expected 1 selector or at-rule, was "bootstrap-sass/..."
in /Users/joebob/Development/vue-webpack-starter/node_modules/bootstrap-sass-webpack/bootstrap-sass.config.js (line 2, column 1)
# ./~/bootstrap-sass-webpack/~/style-loader!./~/bootstrap-sass-webpack/~/css-loader!./~/sass-loader!./~/bootstrap-sass-webpack/bootstrap-sass-styles.loader.js!./~/bootstrap-sass-webpack/bootstrap-sass.config.js 4:2-458
This is what I do using webpack-simple template and bootstrap-sass (https://github.com/vuejs-templates/webpack-simple):
package.json
{
"name": "Example",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "Aleix Fabra <aleixfabra#gmail.com>",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"vue": "^2.3.3"
},
"devDependencies": {
"babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-preset-env": "^1.5.1",
"bootstrap-sass": "^3.3.7",
"cross-env": "^3.0.0",
"css-loader": "^0.25.0",
"file-loader": "^0.9.0",
"node-sass": "^4.5.0",
"sass-loader": "^5.0.1",
"vue-loader": "^12.1.0",
"vue-template-compiler": "^2.3.3",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5"
}
}
main.js
window.$ = window.jQuery = require('jquery')
import 'bootstrap-sass'
import 'bootstrap-sass/assets/stylesheets/_bootstrap.scss'
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
webpack.config.js
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!sass-loader'
},
{
test: /\.(otf|eot|woff|woff2|ttf|svg)$/,
loader: 'file-loader'
},
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
You should install the sass-loader:
npm install sass-loader --save-dev