How to use sass in VUE application? - vue.js

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.

Related

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

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.

Vue JS: Build command `npm run build` is not able to generate `index.html`

When I'm running npm run build, it is not creating index.html in the dist/ directory. The reason I need index.html is that I want to deploy my Vue project to AWS EC2 (/var/www/html/). What to do to generate this index.html?
My dist/ directory structure after running npm run build:
My package.json:
{
"name": "proto",
"description": "Prototype",
"version": "1.0.0",
"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": {
"#melmacaluso/vue-modal": "^2.1.0",
"firebase": "^7.14.2",
"fusioncharts": "^3.15.1-sr.1",
"vue": "^2.5.11",
"vue-fusioncharts": "^3.0.4",
"vue-router": "^3.1.6",
"vuex": "^3.3.0"
},
"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",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}
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'
],
}, {
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
})
])
}
The build command output:
$ npm run build
> proto#1.0.0 build C:\Users\john\Documents\VUE\dummy_prototype_1
> cross-env NODE_ENV=production webpack --progress --hide-modules
In your webpack.config.js, scroll down then add the HtmlWebpackPlugin plugin into module.exports.plugins as #Michal Levy suggested.
Updated:
For the error (webpack.js:348 throw err; TypeError: Cannot read property 'make' of undefined), one possible reason is version issue. The solution is downgrade (uninstall then install) html-webpack-plugin to 3.2.0.
Below is new configuration for plugins:
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
}
}),
// below is the plugin you need to add
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, './dist/index.html'), // the path where is the `index.html` generated.
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Just use HtmlWebpackPlugin
It will automatically create (new or from template you provide) index.html in the dist folder and inject any necessary <script> (for js bundles) or <link> (for extracted CSS) tags
As it seems you already have index.html template, use template option - see the docs

Unable to correct error to load <lang="scss"> in vue style

i am developing an application with webpackconfig , i have installed "sass-loader" and "node-sass" and tried all the different configurations i have found both in the official webpack documentation and in other web references to load scss and i can't solve the following error
ERROR in ./node_modules/css-loader?sourceMap!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-311067c8","scoped":false,"hasInlineConfig":false}!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/devis/animal.vue
ERROR in ./src/main.js
Module not found: Error: Can't resolve 'style-loader, css-loader, sass-loader' in 'C:\Users\juan.urra\Desktop\pricing_3108'
# ./src/main.js 9:0-46
# multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js
this is my package.json
{
"name": "vue-cli",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "",
"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",
"serve": "vue-cli-service serve"
},
"dependencies": {
"axios": "^0.19.2",
"bootstrap": "^4.5.2",
"bootstrap-vue": "^2.16.0",
"vue": "^2.5.11",
"vue-mq": "^1.0.1",
"vue-router": "^3.3.4",
"vue-style-loader": "^4.1.2",
"vuelidate": "^0.7.5",
"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.11",
"less": "^3.12.2",
"less-loader": "^7.0.0",
"node-sass": "^4.14.1",
"sass": "^1.26.10",
"sass-loader": "^9.0.3",
"style-loader": "^1.2.1",
"stylus": "^0.54.8",
"stylus-loader": "^3.0.2",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.12.0",
"webpack-dev-server": "^2.9.1"
}
}
this is my webpack.config
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'
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
// other vue-loader options go here
}
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
watch: true,
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"',
BASE_URL_API: '"https:///"',
USER: '"j.doe1"',
PASSWORD: '"password"',
PAYMENT_URL: '"https:///"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
} else {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
BASE_URL_API: '"https:///"',
USER: '"j.doe1"',
PASSWORD: '"password"',
PAYMENT_URL: '"https:///"'
}
})
])
}
and the error jumps when I refer to the lang "scss" in the style tag
Should I make any reference in my main.js? I haven't seen anything about it in any reference
I'm stuck in this error and I can't fix it in any way! Someone who can make me see the error!
Greetings and thanks in advance for your time and help
after trying all the solutions I found on the web and not seeing the error I found a github repository with a similar project in structure to mine and reviewing the package.json I saw that the only difference was the version of 'sass-loader'. Mine was by default the last version and yours was an older one, so I downloaded the version to yours and the problem was solved. I understand that there is some kind of incompatibility between webpack and sass loader versions, although I have not found any reference to the issue. I hope to help.

Webpack - trying to route/compile my CSS and JS files into CSS and JS specific sub-folders within dist/ folder

I'm pretty new to webpack in general. Just a couple of days in really. For the most part I feel like I've made some pretty good progress on at setting up and integrating webpack into my local development environment. Quite a few bugs and command line errors along the way but I was able to work through most of them up to now. Shout out to Maxmillian Schwärzmuller's short YT series on Webpack to get me started.
Now I'm trying to re-purpose/expand on some of the concepts I've picked up however I'm not yet having any success getting my npm run build (this would be the production command) to compile my CSS files into CSS and JS subfolders (off the root of the site) respectively.
I felt like I was making more progress with my attempts to use the file-loader package within my JS and CSS specific test blocks but now I'm wondering if I'm not either misunderstanding the purpose of the file-loader package or simply not configuring it correctly.
Here are the contents of my webpack.config.js file:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const extractPlugin = new ExtractTextPlugin({
filename: 'styles.css'
});
module.exports = {
entry: './src/js/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['babel-preset-env']
}
}
// attempted to replicate the same use statement as seen below for the jpg/png test
// and only app.js (not app.bundle.js) was dropped into dist/js/
// {
// loader: 'file-loader',
// options: {
// name: '[name].[ext]',
// outputPath: 'js/',
// publicPath: 'js/'
// }
// }
]
},
{
test: /\.scss$/,
use: extractPlugin.extract({
use: ['css-loader', 'sass-loader']
})
// attempted to modify/replicate the above use statement
// use: [
// {
// loader: 'css-loader',
// loader: 'sass-loader'
// loader: 'file-loader',
// options: {
// name: '[name].[ext]',
// outputPath: 'css/',
// publicPath: 'css/'
// }
// }
// ]
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: /\.(jpg|png)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
publicPath: 'images/'
}
}
]
},
{
test: /\.html$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
],
exclude: path.resolve(__dirname, 'src/index.html')
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
extractPlugin,
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html'
}),
new CleanWebpackPlugin(['dist'])
]
};
Here is the package.json file:
{
"name": "nodomaintoseehere.com",
"version": "1.0.0",
"description": "Site repository v1.0",
"private": true,
"main": "./src/app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server",
"build": "webpack -p"
},
"author": "Jeremy Wilson",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.3.1",
"node-sass": "^4.9.3",
"sass-loader": "^7.1.0",
"webpack": "^3.12.0",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^2.11.2"
},
"dependencies": {
"bootstrap": "^4.1.3",
"lodash": "^4.17.10"
}
}
And finally the app.js file
import '../css/styles.scss';
import 'babel-polyfill';
import $ from 'jquery';
Thanks in advance.
Putting assets into different subfolders does not make any differece in performance, nor in use since those are going to sit on your static server everytime until it is redeployed.
There is no way to output js files to js folder since there is no option on babel loader and file-loader does not handle js, they just emit the file, in your case it would endup with duplicated files at the end. File-loader is not ideal to work with javascript files.
For css, you can configure extract-text-plugin.
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const extractPlugin = new ExtractTextPlugin({
filename: 'css/styles.css' // <---
});
module.exports = {
entry: './src/js/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['babel-preset-env']
}
}
]
},
{
test: /\.scss$/,
use: extractPlugin.extract({
use: ['css-loader', 'sass-loader']
})
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: /\.(jpg|png)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
publicPath: 'images/'
}
}
]
},
{
test: /\.html$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
}
],
exclude: path.resolve(__dirname, 'src/index.html')
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
extractPlugin,
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html'
}),
new CleanWebpackPlugin(['dist'])
]
};

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