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

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'])
]
};

Related

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.

Webpack build fails for IE (11)

Trying to setup webpack to build my .js and .vue files.
Seems to no transpile _name() {} style function to regular JavaScript.
Thought it should do that out of the box, straight into commons js unless otherwise specified.
No idea why, it's crashing only in IE with some generic JS syntax error about semi colon out of place.
I guess some little flag, setting, something, somewhere.
Looking for some suggestions here.
ex vue
<script>
export default {
computed: {
_name() {
return 'blah';
}
}
};
</script>
package.json
"#babel/core": "7.0.0-beta.42",
"#babel/plugin-proposal-object-rest-spread": "7.0.0-beta.42",
"#babel/preset-env": "7.0.0-beta.42",
"babel-loader": "8.0.0-beta.2",
"vue-loader": "9.5.1",
"vue-style-loader": "1.0.0",
"sass-loader": "3.2.3",
"node-sass": "^4.1.1",
"css-loader": "0.25.0",
"style-loader": "0.13.1",
"vue-html-loader": "1.2.3",
"file-loader": "^0.8.4",
"webpack": "3.4.1",
"webpack-dev-server": "1.16.1",
"webpack-stream": "3.2.0",
"copy-webpack-plugin": "3.0.1",
"replace-webpack-plugin": "0.1.2",
"uglifyjs-webpack-plugin": "1.2.7"
config
entry: [__dirname + '/../src/bootstrap.js'],
output: {
path: __dirname + '/../public',
filename: 'app.min.js',
chunkFilename: "[name].[chunkhash:4].js",
publicPath: '/',
},
plugins: [
new CopyWebpackPlugin(
(function () {
var copy = [{
to: '',
from: __dirname + '/../src/core/assets'
}, {
to: '',
from: __dirname + '/../src/app/assets'
}];
if (data.copy) {
copy.concat(data.copy);
}
return copy;
})()
),
new ReplacePlugin({
skip: false,
entry: 'src/index.html',
output: '/public/index.html',
hash: '[hash]',
data: {
scripts: data.scripts
}
})
],
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}, {
test: /\.vue$/,
// exclude: /node_modules/,
loader: 'vue-loader',
options: {
loaders: {
js: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
},
sass: 'sass-loader'
}
}
}]
}
build looks like this
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony default export */ __webpack_exports__["default"] = ({
props: ['name', 'timeout', 'max'],
computed: {
_name() {
return this.name || 'global';
},
...
EDIT:
In the end it was just a matter of adding a few specific transform plugins in the .babelrc file at the root. Probably better way to do this via config. Took a while to match the transforms to each error, but the following set worked for me.
{
"plugins": [
"#babel/plugin-transform-spread",
"#babel/plugin-transform-destructuring",
"#babel/plugin-transform-block-scoping",
"#babel/plugin-transform-arrow-functions",
"#babel/plugin-transform-template-literals",
"#babel/plugin-transform-computed-properties",
"#babel/plugin-transform-shorthand-properties"
]
}
Note: each plugin needs to be installed as a dependency also.
Since it is a custom webpack configuration and it is not clear there is any additional configuration to babel, try to add #babel/plugin-transform-shorthand-properties plugin to babel-loader options for .vue files.
loaders: {
js: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-transform-shorthand-properties']
}
},
sass: 'sass-loader'
}
from the output it is confirmed that shorthand property is not getting transpiled
you are using the shorthand property of ES6 which is not supported on iE you need to configure the babel config so that it transpiled this into older version ( for more info about browser support visit this link)
to make your babel config compatible for ie use something like this in babelrc
{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "ie >= 11"]
},
"useBuiltIns": true
}],
]
}
if that dosen't work try changing you devtool config in webpack (for example eval to something else ) and check this thread of github

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

less-loader issue with webpack

I have an issue with loading flat-ui.less from the module. Need help.
I require flat-ui like this require('flat-ui/less/flat-ui.less'); Also the versions for each related loader are "less-loader": "^0.7.7", "css-loader": "^0.9.0", "style-loader": "^0.8.1",
My webpack.config.js is like this:
var path = require("path");
var webpack = require("webpack");
module.exports = {
// This is the main file that should include all other JS files
entry: "./public/scripts/main.jsx",
target: "web",
debug: true,
devtool: "source-map",
// We are watching in the gulp.watch, so tell webpack not to watch
watch: true,
watchDelay: 300,
output: {
path: path.join(__dirname, "dist", "assets"),
publicPath: "/assets/",
// If you want to generate a filename with a hash of the content (for cache-busting)
// filename: "main-[hash].js",
filename: "main.js",
chunkFilename: "[chunkhash].js"
},
resolve: {
// Tell webpack to look for required files in bower and node
modulesDirectories: ['bower_components', 'node_modules', 'public'],
fallback: ['./public']
},
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.less$/, loader: "style-loader!css-loader!less-loader" },
{ test: /\.gif/, loader: "file-loader!url-loader?limit=10000&minetype=image/gif" },
{ test: /\.jpg/, loader: "file-loader!url-loader?limit=10000&minetype=image/jpg" },
{ test: /\.png/, loader: "file-loader!url-loader?limit=10000&minetype=image/png" },
{ test: /\.jsx/, loader: "jsx-loader" },
// required for bootstrap/flat-ui
{ test: /\.woff$/, loader: "url-loader?prefix=font/&limit=5000&mimetype=application/font-woff" },
{ test: /\.ttf$/, loader: "file-loader" },
{ test: /\.eot$/, loader: "file-loader" },
{ test: /\.svg$/, loader: "file-loader" },
],
noParse: /\.min\.js/
},
plugins: [
// If you want to minify everything
new webpack.optimize.UglifyJsPlugin()
]
};
Unfortunately, I got this
ERROR in ./~/css-loader!./~/less-loader!./~/flat-ui/less/flat-ui.less
Module not found: Error: Cannot resolve 'file' or 'directory' ./fonts/lato/lato-black.eot in /Users/Hao/Documents/project/node_modules/flat-ui/less
# ./~/css-loader!./~/less-loader!./~/flat-ui/less/flat-ui.less 2:66-104 2:118-156
Any idea of what's going on here??
Thanks in advance.
The issue here is that your application is looking for lato-black.eot in /Users/Hao/Documents/project/node_modules/flat-ui/less, but it's not there. That's because it's being created somewhere else, I'm guessing /Users/Hao/Documents/project/public. In any case, find where it is being created, then add this to your webpack.config.js:
{ test: /\.eot$/, loader: "file-loader&name=./path/to/file/[hash].[ext]" }
This will tell your application where to look for all eot files. You can do the same with all the other file types as well. Here's a link to the closed issue on the webpack github: https://github.com/webpack/file-loader/issues/32. Hope this helps.