Unable to compile and run application with more then 8 modules using webpack 4 and lazy loading with AOT.
If i use ExtractTextWebpackPlugin to extract less file , Then webpack hangs at 70% and not give any error. At same time i remove ExtractTextWebpackPlugin and remove all stylesheet from application then webpack runs properly.
I have following devdependencies in package.json file:
"devDependencies": {
"#angular/compiler-cli": "5.2.9",
"#angularclass/hmr": "2.1.3",
"#angularclass/hmr-loader": "3.0.4",
"#ngtools/webpack": "6.0.0-rc.5",
"#types/node": "7.0.7",
"angular-mocks": "^1.6.2",
"angular-router-loader": "0.8.5",
"angular2-template-loader": "0.6.2",
"autoprefixer": "8.2.0",
"awesome-typescript-loader": "5.0.0",
"browserify": "^14.1.0",
"clean-webpack-plugin": "0.1.19",
"compression-webpack-plugin": "1.1.11",
"copy-webpack-plugin": "4.5.1",
"css-hot-loader": "^1.3.9",
"css-loader": "0.28.11",
"css-to-string-loader": "^0.1.3",
"csso-webpack-plugin": "1.0.0-beta.10",
"del": "latest",
"gulp": "^3.9.1",
"gulp-sass": "latest",
"gulp-sourcemaps": "latest",
"gulp-tslint": "latest",
"gulp-typescript": "latest",
"html-loader": "0.5.4",
"html-webpack-plugin": "2.30.1",
"http-server": "^0.10.0",
"iso-morphic-style-loader": "2.0.1",
"jasmine-core": "^2.6.4",
"karma": "2.0.0",
"karma-browserify": "^5.1.1",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "1.1.1",
"karma-phantomjs-launcher": "1.0.4",
"karma-sourcemap-loader": "0.3.7",
"karma-webpack": "2.0.9",
"less": "2.7.3",
"less-loader": "4.0.5",
"merge-jsons-webpack-plugin": "1.0.14",
"mini-css-extract-plugin": "^0.4.0",
"postcss-loader": "^1.2.0",
"pushstate-server": "3.0.1",
"raw-loader": "^0.5.1",
"remap-istanbul": "^0.9.1",
"replace-webpack-plugin": "0.1.2",
"string-replace-loader": "2.1.1",
"style-loader": "^0.13.2",
"systemjs": "^0.19.27",
"systemjs-builder": "latest",
"to-string-loader": "^1.1.4",
"ts-helpers": "1.1.2",
"tslint": "latest",
"typescript": "2.8.3",
"typings": "2.1.1",
"uglifyjs-webpack-plugin": "1.2.4",
"watchify": "^3.9.0",
"webpack": "4.5.0",
"webpack-cli": "2.0.14",
"webpack-merge": "4.1.2"
}
and following is webpack.config.js file:
var path = require('path');
var webpack = require('webpack');
var Autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var helpers = require('./webpack.helpers');
var MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
var AngularCompilerPlugin = require('#ngtools/webpack').AngularCompilerPlugin;
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
var ReplacePlugin = require('replace-webpack-plugin');
module.exports = function (options)
{
isProd = options.env === 'production';
return {
mode: options.env,
entry: {
'polyfills': './polyfills.ts',
'intl': './datetimepolyfills.ts',
'globals': [
'reflect-metadata',
'rxjs'
],
'app': './public/app/main.ts', // our angular app
'style': './public/assets/style/app.less'
},
output: {
path: path.join(__dirname, 'wwwroot/'),
filename: 'app/[name]-[hash].bundle.js',
publicPath: "/"
},
resolve: {
modules: [
'node_modules',
path.resolve(__dirname, 'app')
],
extensions: ['.ts', '.js', '.json', '.css', '.less', '.html']
},
module: {
rules:
[
{
test: /\.ts$/,
loaders:
[
'#ngtools/webpack',
'awesome-typescript-loader',
'angular2-template-loader?keepUrl=true',
'angular-router-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.css$/,
loader: 'css-to-string-loader!iso-morphic-style-loader!css-loader'
},
{
test: /\.scss$/,
include: /node_modules/,
loader: 'css-to-string-loader!iso-morphic-style-loader!raw-loader'
},
{
test: /\.less$/,
exclude: helpers.root('node_modules', 'app'),
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['to-string-loader', 'css-loader', 'less-loader']
})
},
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['iso-morphic-style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpg|gif|ico|woff|woff2|ttf|svg|eot|json)$/,
exclude: /node_modules/,
loader: "file?name=assets/[name]-[hash:6].[ext]",
}
],
},
plugins: [
new CleanWebpackPlugin(
[
'./wwwroot'
]
),
new ExtractTextPlugin("./assets/[name].css"),
new AngularCompilerPlugin({
tsConfigPath: './tsconfig.json',
entryModule: 'public/app/app.module#AppModule',
skipMetadataEmit: true
}),
new CopyWebpackPlugin([{
from: './node_modules/syx-general-components/src/fonts/**',
to: "./assets/fonts/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './node_modules/syx-general-components/src/scripts/**',
to: "./assets/scripts/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './node_modules/syx-general-components/src/img/**',
to: "./assets/img/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/assets/docs/*.*',
to: "./assets/docs/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/assets/img/*.*',
to: "./assets/img/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/config/*.*',
to: "./config/",
flatten: true
}]),
new ReplacePlugin({
entry: './public/index.html',
hash: '[hash]',
output: './wwwroot/index.html'
}),
new CopyWebpackPlugin([{
from: './public/print-ticket.html',
to: "./",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/assets/scripts/**',
to: "./assets/scripts/",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/favicon*',
to: "./",
flatten: true
}]),
new CopyWebpackPlugin([{
from: './public/favicon_*.*',
to: "./",
flatten: true
}]),
new webpack.optimize.ModuleConcatenationPlugin(),
new MergeJsonWebpackPlugin({
"output": {
"groupBy": [{
"pattern": "{./public/assets/locale/*-nl.json,./node_modules/syx-general-components/src/locale/*-nl.json}",
"fileName": "./assets/locale/locale-nl.json"
},
{
"pattern": "{./public/assets/locale/*-en.json,./node_modules/syx-general-components/src/locale/*-en.json}",
"fileName": "./assets/locale/locale-en.json"
},
{
"pattern": "{./public/assets/locale/*-fr.json,./node_modules/syx-general-components/src/locale/*-fr.json}",
"fileName": "./assets/locale/locale-fr.json"
}
]
}
})
],
optimization: {
noEmitOnErrors: true,
minimize: true,
minimizer: [
// we specify a custom UglifyJsPlugin here to get source maps
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: true,
ecma: 5,
mangle: true
},
sourceMap: false
})
]
},
devServer: {
historyApiFallback: true,
stats: 'minimal',
outputPath: path.join(__dirname, 'wwwroot/')
}
}
};
If i use ExtractTextWebpackPlugin to extract less file , Then webpack hangs at 70%. At same time i remove ExtractTextWebpackPlugin and remove all stylesheet from application then webpack runs properly.
Can anyone help with this ?
Related
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.
I am new to setting up the tailwind/postcss configuration using Intertia.js/Vue.js and would appreciate some guidance with my configuration files!
My goal is to be able to write postcss/scss style within my vue components, with the ability to use the postcss #apply functionality for example, like so:
Navigation.vue:
<style lang="postcss">
.nav-items {
#apply bg-red;
}
</style>
With the current configuration setup I have, I am not getting any errors compiling however the style is not being applied, it doesn't appear in the Styles in console for the element.
webpack.mix.js
const mix = require('laravel-mix')
const path = require('path')
const purgecss = require('#fullhuman/postcss-purgecss')
const tailwindcss = require('tailwindcss')
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css/app.css')
.options({
postCss: [
tailwindcss('tailwind.config.js'),
...mix.inProduction() ? [
purgecss({
content: ['./resources/views/**/*.blade.php', './resources/js/**/*.vue'],
defaultExtractor: content => content.match(/[\w-/:.]+(?<!:)/g) || [],
whitelistPatternsChildren: [/nprogress/],
}),
] : [],
],
})
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.js',
'#': path.resolve('resources/js'),
ziggy: path.resolve('vendor/tightenco/ziggy/src/js/route.js'),
},
},
module: {
rules: [
{
test: /\.postcss$/,
loaders: [
"style-loader",
{
loader: "css-loader",
options: { modules: true, importLoaders: 1 }
},
"postcss-loader",
]
}
]
}
})
.version()
.sourceMaps()
tailwind.config.js:
const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
purge: [
'./resources/views/**/*.blade.php',
'./resources/css/**/*.css',
],
sourceMap: false,
theme: {
//...
},
plugins: [],
}
postcss.config.js:
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
],
};
package.json:
{
//...
"devDependencies": {
"#babel/preset-env": "^7.9.6",
"#tailwindcss/custom-forms": "^0.2.1",
"axios": "^0.19",
"cross-env": "^7.0",
"css-loader": "^3.5.3",
"laravel-mix": "^5.0.1",
"laravel-mix-tailwind": "^0.1.0",
"lodash": "^4.17.13",
"postcss-css-variables": "^0.17.0",
"postcss-loader": "^3.0.0",
"postcss-nesting": "^7.0.1",
"resolve-url-loader": "^3.1.0",
"sass": "^1.15.2",
"sass-loader": "^8.0.0",
"style-loader": "^1.2.1",
"tailwindcss": "^1.4",
"vue-svgicon": "^3.2.6",
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"#babel/plugin-syntax-dynamic-import": "^7.8.3",
"#inertiajs/inertia": "^0.1.9",
"#inertiajs/inertia-vue": "^0.1.4",
"alpinejs": "^2.3.5",
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"postcss-import": "^12.0.1",
"postcss-nested": "^4.2.1",
"postcss-nested-ancestors": "^2.0.0",
"vue": "^2.6.11",
"vue-i18n": "^8.17.7",
"vue-meta": "^2.3.3"
}
}
Add this to webpack.config.js :
module: {
rules: [
{
test: /\.(postcss)$/,
use: [
'vue-style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader'
]
}
],
},
Found here https://github.com/JeffreyWay/laravel-mix/issues/2211#issuecomment-546123921
useing vue-cli4
Using UglifyJsPlugin then leads to a series of problems because I want to compress the package size of the component to optimize the server response
Babel. Config. Js es2015 has been replaced # Babel/preset - env I did the following configuration
There is still a syntax validation problem
package.json
"dependencies": {
"#babel/preset-react": "^7.9.4",
"#babel/preset-stage-3": "^7.8.3",
"babel": "^6.23.0",
"babel-plugin-transform-runtime": "^7.0.0-beta.3",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.4.1",
"bootstrap-vue": "^2.12.0",
"cli": "^1.0.1",
"core-js": "^3.6.4",
"markdown-loader": "^5.1.0",
"marked": "^0.8.2",
"mavon-editor": "^2.8.3",
"register-service-worker": "^1.7.1",
"transform-runtime": "0.0.0",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue": "^2.6.11",
"vue-router": "^3.1.6"
},
"devDependencies": {
"#babel/cli": "^7.8.4",
"#babel/core": "^7.9.0",
"#babel/plugin-proposal-class-properties": "^7.4.4",
"#babel/plugin-transform-runtime": "^7.4.4",
"#babel/preset-env": "^7.9.5",
"#babel/runtime": "^7.4.5",
"#vue/cli-plugin-babel": "^4.3.1",
"#vue/cli-plugin-eslint": "^4.3.1",
"#vue/cli-plugin-pwa": "^4.3.1",
"#vue/cli-plugin-router": "^4.3.1",
"#vue/cli-service": "^4.3.1",
"babel-loader": "^7.1.5",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"sass-loader": "^8.0.2",
"sass-resources-loader": "^2.0.3",
"style-loader": "^1.1.4",
"vue-markdown-loader": "^2.4.1",
"vue-template-compiler": "^2.6.11"
}
babel.config.js
module.exports = {
["#babel/preset-env", {
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]
}
vue.config.js
const path = require('path');
const CompressionPlugin = require('compression-webpack-plugin')
// 配置代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
/*配置cdn 引用加速*/
const cdn = {
css: ['https://cdn.bootcss.com/element-ui/2.13.1/theme-chalk/index.css',
'https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css'
],
js: [
'https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js',
'https://unpkg.com/vue/dist/vue.js',
'https://unpkg.com/element-ui/lib/index.js',
'https://cdn.bootcss.com/element-ui/2.13.1/index.js',
]
}
module.exports = {
publicPath: './',
outputDir: 'dist',
lintOnSave: true,
chainWebpack: (config) => {
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({bypassOnDebug: true})
.end()
config.module.rule('md')
.test(/\.md/)
.use('vue-loader')
.loader('vue-loader')
.end()
.use('vue-markdown-loader')
.loader('vue-markdown-loader/lib/markdown-compiler')
.options({
raw: true
})
config.module.rule('js').test(/\.js$/).use('babel-loader').loader('babel-loader')
/* 配置 babel-loader */
const babel_loader = config.module.rule('babel-loader')
babel_loader.exclude.add(/(node_modules|bower_components)/)
babel_loader.test(/\.(e|j)s$/).use('babel-loader').loader('babel-loader')
if (process.env.NODE_ENV === 'production') {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
});
if (process.env.npm_config_report) {
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
.end();
config.plugins.delete('prefetch')
}
} else {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
});
}
},
configureWebpack: (config) => {
config.entry.app = ["babel-polyfill", "./src/main.js"];
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
config.mode = 'production'
return {
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
warnings: false,
compress: {
pure_funcs: ['console.log', 'console.debug']//移除console
}
}
})
]
},
externals: {
/* 包名 : 全局变量名*/
'vue': 'Vue',
/*
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios',*/
// "Bootstrap": "bootstrap",
"elementui": 'ElementUI ',
},
plugins: [
//生产环境自动删除console
/* new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
pure_funcs: ['console.log']//移除console
},
/!* compress: {
warnings: false,
drop_debugger: true,
drop_console: true,
},*!/
},
sourceMap: false,
parallel: true,
}),*/ new CompressionPlugin({
test: /\.js$|\.html$|\.css/, //匹配文件名
threshold: 10240, //对超过10k的数据进行压缩
deleteOriginalAssets: false //是否删除原文件
})]
}
} else if (process.env.NODE_ENV === 'development') {
config.mode = 'development';
Object.assign(config, {
resolve: {
alias: {
'#': path.resolve(__dirname, './src'),
'#c': path.resolve(__dirname, './src/components')
}
}
});
return {
externals: {
'vue': 'Vue',
"elementui": 'ElementUI ',
},
plugins: [new CompressionPlugin({
test: /\.js$|\.html$|\.css/,
threshold: 10240,
deleteOriginalAssets: false
})]
}
}
},
productionSourceMap: false,
css: {
extract: false,
sourceMap: false,
loaderOptions: {},
requireModuleExtension: false
},
parallel: require('os').cpus().length > 1,
pwa: {},
devServer: {
open: process.platform === 'darwin',
host: '0.0.0.0',
port: 2001,
https: false,
hotOnly: false,
open: true,
proxy: {
'/data': {
target: 'http://localhost:7000',
changeORIGIN: true
}
},
before: (app) => {
}
},
pluginOptions: {}
}
The above is the full configuration of my project. This problem has been bothering me for many days. I have tried many methods, but they have no effect
We are switching our vue application over to use vue.config.js instead of webpack.config.js, and I am encountering some issues when trying to do a vue-cli-service build. The main error I am seeing is:
Error: [VueLoaderPlugin Error] No matching use for vue-loader is found.
Make sure the rule matching .vue files include vue-loader in its use.
For reference, here are our package.json, vue.config.js, and babel.config.js
I'm sure there are some things in the vue.config.js that could be cleaned up, but ignoring some of those things, I believe our VueLoaderPlugin should be set up correctly, and it was working in the webpack.config.js before getting moved over to vue.config.js
package.json
{
"name": "project-ui",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "vue-cli-service serve",
"start-dev": "vue-cli-service serve --mode development",
"build-dev": "vue-cli-service build --mode development",
"build-stg": "vue-cli-service build --mode stage --dest dist-stage",
"build-prod": "vue-cli-service build --mode production --dest dist-prod",
"lint": "vue-cli-service lint",
"test": "jest"
},
"dependencies": {
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"axios": "^0.18.0",
"bootstrap": "^4.3.1",
"vue": "^2.6.10",
"vue-loader": "^15.7.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
"#babel/core": "^7.0.0-rc.1",
"#babel/preset-env": "^7.0.0-rc.1",
"#vue/cli-plugin-babel": "^3.5.0",
"#vue/cli-plugin-eslint": "^3.5.0",
"#vue/cli-service": "^3.5.0",
"#vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"clean-webpack-plugin": "^2.0.1",
"cross-env": "^5.2.0",
"eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0",
"file-loader": "^3.0.1",
"jest": "^24.5.0",
"jest-serializer-vue": "^2.0.2",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"sass-loader": "^7.1.0",
"vue-jest": "^3.0.4",
"vue-template-compiler": "^2.5.21",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1",
"webpack-merge": "^4.2.1",
"webpack-serve": "^3.0.0-beta.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"jest": {
"verbose": true,
"moduleFileExtensions": [
"js",
"vue"
],
"moduleNameMapper": {
"^#/(.*)$": "<rootDir>/src/$1"
},
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"description": "## Project setup ``` npm install ```",
"main": "babel.config.js",
"keywords": [],
"author": "",
"license": "ISC"
}
vue.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const env = require(process.env.VUE_APP_NODE_ENV === '' ? './.env' : './.env.' + process.env.VUE_APP_NODE_ENV);
const setPath = function(folderName) {
return path.join(__dirname, folderName);
}
const buildingForLocal = process.env.VUE_APP_NODE_ENV === 'local';
const extractHTML = new HtmlWebpackPlugin({
title: 'Project',
filename: 'index.html',
template: 'public/index.html',
inject: true,
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
html5: true,
minifyCSS: true,
removeComments: true,
removeEmptyAttributes: true
},
environment: process.env.VUE_APP_NODE_ENV,
isLocalBuild: buildingForLocal,
imgPath: (!buildingForLocal) ? 'assets' : 'src/assets'
});
module.exports = {
publicPath: '/',
outputDir: buildingForLocal ? path.resolve(__dirname) : setPath(process.env.VUE_APP_DROP_LOCATION),
configureWebpack: {
entry: [
'./src/main.js'
],
output: {
filename: buildingForLocal ? '[name].js' : '[name].[hash].js'
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
vue: buildingForLocal ? 'vue/dist/vue.js' : 'vue/dist/vue.min.js'
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'babel-loader'
}
}
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: "babel-loader",
options: { presets: ['#babel/preset-env'] }
}]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader'
},
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]',
useRelativePath: buildingForLocal
}
}
]
},
plugins: [
extractHTML,
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
//filename: "css/styles.[hash].css",
//chunkFilename: "[id].css"
}),
new webpack.DefinePlugin({
'process.env': env
}),
new CleanWebpackPlugin(),
new VueLoaderPlugin()
],
optimization: {
splitChunks: false
},
mode: buildingForLocal ? 'development' : 'production'
},
devServer: {
historyApiFallback: true,
noInfo: false
}
};
babel.config.js
module.exports = {
"presets": [
["#babel/preset-env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}]
],
"plugins": ["#babel/plugin-syntax-dynamic-import"],
"env": {
"test": {
"presets": [
["#babel/preset-env", { "targets": { "node": "current" }}]
]
}
}
}
I'm trying to update my Aurelia project that uses webpack so I can require .scss files in my templates. I've looked at the Aurelia Skeleton project for webpack and have followed this guide to come up with my webpack.config which is listed below. I have also included my package.json file.
I am able to load styles now, but have come across a perplexing issue. None of the my bind statements work anymore. The code itself didn't change and was working fine before this update attempt. I tried using two-way, one-way, etc, but that didn't work either. The #bindable property is always undefined.
<my-custom-element value.bind="something"></my-custom-element>
In MyCustomElement, value is always undefined although something is set properly.
I have tried walking back the package versions and I think it has to do with aurelia-bootstrapper, but I'm not sure.
I'm out of ideas on how to debug this issue. Any help would be much appreciated.
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const DashboardPlugin = require('webpack-dashboard/plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { optimize: { CommonsChunkPlugin }, ProvidePlugin } = require('webpack')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const project = require('./package.json');
// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || []
const when = (condition, config, negativeConfig) =>
condition ? ensureArray(config) : ensureArray(negativeConfig)
// primary config:
const title = 'Radar';
const outDir = path.resolve(__dirname, 'dist');
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';
// If not done this way the plugin will try to load when only a build is required and cause it to hang.
const addDashboardPlugin = process.env.npm_lifecycle_event === 'webpack' ? [] : [new DashboardPlugin({
port: 3333
})];
const metadata = {
port: process.env.WEBPACK_PORT || 9000,
host: process.env.WEBPACK_HOST || 'localhost'
};
const cssRules = [
{ loader: 'css-loader' },
{
loader: 'postcss-loader',
options: { plugins: () => [require('autoprefixer')({ browsers: ['last 2 versions'] })] }
}
]
module.exports = ({ production, server, extractCss, coverage } = {}) => ({
resolve: {
extensions: ['.js'],
modules: [srcDir, 'node_modules'],
},
entry: {
app: ['aurelia-bootstrapper'],
aurelia: Object.keys(project.dependencies).filter(dep => dep.startsWith('aurelia-')),
vendor: Object.keys(project.dependencies).filter(dep => !dep.startsWith('aurelia-'))
},
devtool: production ? 'source-map' : 'inline-source-map',
output: {
path: outDir,
publicPath: baseUrl,
filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js',
},
devServer: {
contentBase: outDir,
// serve index.html for all 404 (required for push-state)
historyApiFallback: true,
port: metadata.port,
host: metadata.host,
watchOptions: {
aggregateTimeout: 300,
poll: 1000
}
},
module: {
rules: [
{
test: /\.scss$/i,
issuer: [{ not: [{ test: /\.html$/i }] }],
loaders: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap']
},
{
test: /\.scss$/i,
issuer: [{ test: /\.html$/i }],
loaders: ['css-loader?sourceMap', 'sass-loader?sourceMap']
},
// CSS required in JS/TS files should use the style-loader that auto-injects it into the website
// only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
{
test: /\.css$/i,
issuer: [{ not: [{ test: /\.html$/i }] }],
use: extractCss ? ExtractTextPlugin.extract({
fallback: 'style-loader',
use: cssRules,
}) : ['style-loader', ...cssRules],
},
{
test: /\.css$/i,
issuer: [{ test: /\.html$/i }],
// CSS required in templates cannot be extracted safely
// because Aurelia would try to require it again in runtime
use: cssRules,
},
{ test: /\.html$/i, loader: 'html-loader' },
{
test: /\.js$/i, loader: 'babel-loader', exclude: nodeModulesDir,
options: coverage ? { sourceMap: 'inline', plugins: ['istanbul'] } : {},
},
{ test: /\.json$/i, loader: 'json-loader' },
// use Bluebird as the global Promise implementation:
{ test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' },
// embed small images and fonts as Data Urls and larger ones as files:
{ test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
{ test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
{ test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
// load these fonts normally, as files:
{ test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
]
},
plugins: [
new AureliaPlugin(),
new ModuleDependenciesPlugin({
'aurelia-dialog': ['./ai-dialog', './ai-dialog-header', './ai-dialog-footer', './ai-dialog-body',
'./attach-focus', './dialog-configuration', './dialog-controller', './dialog-options', './dialog-renderer',
'./dialog-result', './dialog-service', './lifecycle', './renderer'],
'aurelia-chart': ['./elements/chart-element', './attributes/chart-attribute', './observers/model-observer']
}),
new ProvidePlugin({
'Promise': 'bluebird'
}),
new HtmlWebpackPlugin({
template: 'index.ejs',
minify: production ? {
removeComments: true,
collapseWhitespace: true
} : undefined,
metadata: {
title, server, baseUrl
},
}),
new CopyWebpackPlugin([
{ from: 'src/config', to: 'config' },
{ from: 'styles/img', to: 'img' }
]),
...when(extractCss, new ExtractTextPlugin({
filename: production ? '[contenthash].css' : '[id].css',
allChunks: true,
})),
...when(production, new CommonsChunkPlugin({
name: 'common'
})),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.scss$/i,
cssProcessor: require('cssnano'),
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
})
].concat(addDashboardPlugin)
})
package.json
"dependencies": {
"aurelia-animator-css": "^1.0.0",
"aurelia-application-insights": "^1.0.0",
"aurelia-binding": "^1.2.0",
"aurelia-bootstrapper": "^2.1.1",
"aurelia-chart": "^0.2.6",
"aurelia-configuration": "1.0.17",
"aurelia-dependency-injection": "^1.3.1",
"aurelia-dialog": "^1.0.0-beta.3.0.0",
"aurelia-event-aggregator": "^1.0.1",
"aurelia-fetch-client": "^1.1.2",
"aurelia-framework": "^1.1.0",
"aurelia-history": "^1.0.0",
"aurelia-history-browser": "^1.0.0",
"aurelia-logging": "^1.3.1",
"aurelia-logging-console": "^1.0.0",
"aurelia-metadata": "^1.0.3",
"aurelia-notify": "^0.8.1",
"aurelia-pal": "^1.3.0",
"aurelia-pal-browser": "^1.1.0",
"aurelia-path": "^1.0.0",
"aurelia-route-recognizer": "^1.0.0",
"aurelia-router": "^1.3.0",
"aurelia-task-queue": "^1.2.0",
"aurelia-templating": "^1.3.0",
"aurelia-templating-binding": "^1.3.0",
"aurelia-templating-resources": "^1.3.1",
"aurelia-templating-router": "^1.1.0",
"aurelia-validation": "^1.0.0",
"bluebird": "^3.3.5",
"json-loader": "^0.5.4",
... //omitted for clarity
},
"devDependencies": {
"aurelia-loader-nodejs": "^1.0.1",
"aurelia-pal-nodejs": "^1.0.0-beta.1.0.0",
"aurelia-tools": "^1.0.0",
"aurelia-webpack-plugin": "^2.0.0-rc.2",
"autoprefixer": "^7.0.0",
"babel-core": "^6.17.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.0.0",
"babel-plugin-istanbul": "^4.1.3",
"babel-plugin-lodash": "^3.2.10",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.16.0",
"babel-preset-env": "^1.5.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-1": "^6.24.1",
"babel-register": "^6.11.6",
"concurrently": "^2.2.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^3.1.3",
"css-loader": "^0.28.1",
"eslint": "^3.12.2",
"extract-text-webpack-plugin": "^2.1.0",
"file-loader": "^0.9.0",
"html-server": "^0.1.1",
"html-webpack-plugin": "^2.22.0",
"json-loader": "^0.5.4",
"node-sass": "^3.13.0",
"optimize-css-assets-webpack-plugin": "^1.3.2",
"package": "^1.0.1",
"postcss-loader": "^1.3.3",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"sass-loader": "^4.0.2",
"style-loader": "^0.17.0",
"url-loader": "^0.5.8",
"webpack": "^2.6.1",
"webpack-dashboard": "^0.2.0",
"webpack-dev-server": "^2.4.5"
}
nav-bar.html
<template>
<require from='./_nav-bar.scss'></require>
<section class="nav-bar nav-bar__group" data-grid="full">
<div data-grid="full">
<main-menu router.bind="router" data-grid="21"></main-menu>
<user-panel data-grid="3"></user-panel>
</div>
</section>
</template>
main-menu.html
<template class="main-menu">
<ul class="main-menu__nav-list">
<li repeat.for="row of router.navigation">
<a href.bind="row.href"
data-appinsights-category="navigation"
data-appinsights-action="${row.title}"
data-text="${row.title}">
${row.title}
</a>
</li>
</ul>
</template>
main-menu.js
import { bindable, inject } from 'aurelia-framework';
#inject(Element)
export class MainMenuCustomElement {
//This value is always undefined now
#bindable router;
constructor(element) {
this.element = element;
}
toggleMenu() {
//removed for brevity
}
}
I got it to work after adding import babel-polyfill to main.js, changing .babelrc to reference `.babelrc.js like so:
{
"presets": [ "./.babelrc.js" ]
}
I also included .babelrc.js from the skeleton-navigation project.
.babelrc.js
// this file will be used by default by babel#7 once it is released
module.exports = {
"plugins": [
"transform-decorators-legacy",
"transform-class-properties"
],
"presets": [
[
"env", {
"targets": process.env.BABEL_TARGET === 'node' ? {
"node": process.env.IN_PROTRACTOR ? '6' : 'current'
} : {
"browsers": [
"last 2 versions",
"not ie <= 11"
],
"uglify": process.env.NODE_ENV === 'production',
},
"loose": true,
"modules": process.env.BABEL_TARGET === 'node' ? 'commonjs' : false,
"useBuiltIns": true
}
]
]
}