errors when creating webpack config file - visual-studio

I am trying to setup the simplest possible typescript+react-project in visual studio 2017.
I have this webpack.config.js that was changed to work with webpack 2+
The change was from using "loaders" and "preloaders" to "rules".
With the content below I get the error
Module build failed: error TS5014: Failed to parse file 'C:\Users\my project\tsconfig.json': Unexpected token } in JSON at position 4521.
This is the file
module.exports = {
entry: "./Scripts/hello-stackoverflow/index.tsx",
output: { filename: "./dist/bundle.js" },
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
externals: {
"react": "React",
"react-dom": "ReactDOM"
}
};

Related

Webpack compile sass into css file problem

Firstly I'd like to say that I've seen same question but I cannot upvote nor comment to say that I'm in the same need. So it's clearly a duplicate of How to use Webpack 4 to compile Sass files properly?
I'm just trying to compile some sass file into css file using webpack. But webpack creates some useless js files with the same name as the css files.
The folder Structure:
--dist
--src
|--a
|--editor.scss
|--style.scss
|--b
|--editor.scss
|--style.scss
and my dependencies (package.json)
"devDependencies": {
"webpack": "latest",
"webpack-cli": "latest",
"css-loader": "latest",
"sass-loader": "latest",
"node-sass": "latest",
"mini-css-extract-plugin": "latest"
}
here the config I've set up already (webpack.config.js):
const path = require("path");
const context = path.resolve(__dirname);
const output = context + "/dist";
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const entries = {
"/dist/a/editor": "./src/a/editor.scss",
"/dist/a/style": "./src/a/style.scss",
"/dist/b/editor": "./src/b/editor.scss",
"/dist/b/style": "./src/b/style.scss"
};
module.exports = {
context: context,
entry: entries,
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css"
})
],
output: {
path: output
// // publicPath: distBlocks,
// // filename: "[name].js"
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader"
},
{
loader: "sass-loader"
}
]
}
]
}
};
Actual result:
--dist
|--a
|--editor.css
|--editor.js
|--style.css
|--style.js
|--b
|--editor.css
|--editor.js
|--style.css
|--style.js
--src
|--a
|--editor.scss
|--style.scss
|--b
|--editor.scss
|--style.scss
Expected result is the same without those useless js files...
So How webpack is suppose to be configured to get the css file only and no js files from the scss??
UPDATE:
Here is a workaround : webpack-fix-style-only-entries
webpack.config.js
...
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");
...
Module.exports = {
...
plugins: [
new FixStyleOnlyEntriesPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css"
})
],
...
There is a fix but only for the future version of webpack (^5) if understood correctly webpack git

using ES2015 with mocha, karma and headless chrome for testing

I have a problem with setting up a test environment for a single page application. I am able to run my tests with headless chrome via karma and mocha but I can´t write tests with ES6 Syntax.
My current start command is
karma start --browsers ChromeHeadless karma.config.js --single-run
my karma.config.js
module.exports = function(config) {
config.set({
frameworks: ['mocha', 'chai'],
files: ['test/**/*spec.js'],
reporters: ['nyan'],
port: 9876, // karma web server port
colors: true,
logLevel: config.LOG_INFO,
browsers: ['ChromeHeadless'],
autoWatch: true,
singleRun: false, // Karma captures browsers, runs the tests and exits
concurrency: Infinity,
})
}
I am able to write normal tests but cant use ES6 Syntax here. When I try to import some react components I get this error:
HeadlessChrome 0.0.0 (Linux 0.0.0)
Uncaught SyntaxError: Unexpected token import
at http://localhost:9876/base/test/components.spec.js?b89d2ba6de494310860a60ad2e9e25aea5eb3657:2
So I have to setup babel somehow to compile my test files first. When I try to use compilers: ['js:babel-core/register'] in my karma config its not gonna work.
I also have seen that compilers seems to be deprecated soon so I also tried require: ['babel-core/register'] but it still won´t compile to use ES6 for my test files.
Any idea how to configurate my karma file to write my tests with ES6 ?
Just in case its important. This is my webpack.config.js
const path = require('path');
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve('dist'),
filename: 'index_bundle.js'
},
module: {
loaders: [
{test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/},
{test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/}
]
},
plugins: [
new ServiceWorkerWebpackPlugin({
entry: path.join(__dirname, 'src/sw.js'),
}),
HtmlWebpackPluginConfig
],
devServer: {
hot: false,
inline: false,
historyApiFallback: true
}
};
To make things more clear here is a sample project (it's fully runnable, you can fill out files and play around). Just two things to mention: I used jamsine instead of mocha and real 'Chrome' browser instead of headless. Runnable via npm run test command.
files structure
/
karma.conf.js
package.json
sample.js
sampleTest.js
webpack.test.config.js
karma.conf.js:
// Karma configuration
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: ['*Test.js'],
// list of files to exclude
exclude: [],
// preprocess matching files before serving them to the browser
preprocessors: {
'*Test.js': [ 'webpack'] //preprocess with webpack
},
// test results reporter to use
reporters: ['progress'],
// setting up webpack configuration
webpack: require('./webpack.test.config'),
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
browsers: ['Chrome'],
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level how many browser should be started simultaneous
concurrency: Infinity
})
}
package.json (only relevant stuff):
{
"scripts": {
"test": "node_modules/karma/bin/karma start karma.conf.js"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"jasmine-core": "^2.8.0",
"karma": "^2.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.1",
"karma-webpack": "^2.0.9",
"webpack": "^3.10.0"
}
}
sample.js:
export default function(data){
return data;
}
sampleTest.js:
import sample from 'sample';
describe('Sample', function(){
it('is defined', function(){
expect(sample).toBeDefined();
});
it('returns argument', function(){
expect(sample(0)).toBe(0);
})
});
webpack.test.config.js:
module.exports = {
module: {
rules: [
{
test: /tests\/.*\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['babel-preset-env']
}
}
}
]
},
resolve: {
modules: ["node_modules", './'],
extensions: [".js"]
}
};
Karma's webpack plugin is used to inform karma that it should prepare files using webpack and specific webpack configuration before sending them to the browser.
Please note key points:
test files pattern in karma.conf.js
pattern to preprocess files (should match the pattern above)
webpack entry in karma.conf.js file
module entry in webpack.test.config.js
p.s. personally I don't use separate patterns for files, I use a separate file (named, say, tests.webpack.js) to have a single place where the way to find test files is defined:
//make sure you have your directory and regex test set correctly
var context = require.context('.', true, /.*Test\.js$/i);
context.keys().forEach(context);
and have in karma.conf.js (paths are irrelevant to sample project above):
files: [
'tests/tests.webpack.js',
],
preprocessors: {
'./tests/tests.webpack.js': [ 'webpack'] //preprocess with webpack
}
You need to convert ESModule in commonjs module with the babel-plugin-transform-es2015-modules-commonjs plugin
In your .babelrc file :
{
"plugins": [
"transform-es2015-modules-commonjs"
]
}
Update :
You can set the plugin in your webpack configuration :
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: [require('#babel/plugin-transform-es2015-modules-commonjs')]
}
}

How to use Webpack 3 in debug mode

I want to use webpack 3 in debug mode. My webpack.config file is:
module.exports = {
progress: true,
watch: true,
module: {
loaders: [
// JSON
{ test: /\.json$/, loader: "json-loader" },
// React & ES2015
{
test: /.jsx?$/,
loader: 'babel-loader',
//exclude: /node_modules/,
query: {
presets: ['react', 'es2015']
},
}
]
},
plugins: [
new webpack.LoaderOptionsPlugin({
debug: true
})
]
}
The bundle works perfect, but when I press CTRL+P in browser (with debug window open an Source tab selected) it appears only Index.bundle.js. In the past I used braoserify to create bundles and using the following config I could see all bundle files in the console source tab:
browserify({
entries: ['js/index.js'],
transform: [babelify] ,//reactify],
debug: true
})
.bundle()
.on('error', function onError() {
gutil.log(gutil.colors.bgRed(' ! Browserify error: '), arguments);
})
.on('end', function onEnd() {
gutil.log(' > Browserify finished bundling');
})
//.pipe(uglify())
.pipe(source('index-boundle.js'))
.pipe(gulp.dest('js'));
Is there any way to see all budle files in brawser's console using webpac 3?

Laravel + VueJs + Webpack + Karma = world of pain

Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?
VueJs 2x has a very simple example for a component test: Vue Guide Unit testing
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
and then...
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
describe('MyComponent', () => {
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
it ...etc
})
and gives an example of a karma conf file here: https://github.com/vuejs-templates
But the Karma configuration file requires a webpack configuration file
webpack: webpackConfig,
The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.
I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.
Something like this:
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]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
and included it like...
// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;
module.exports = function(config) {
config.set({
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
But I am getting errors that seem to indicate that webpack isn't doing anything.
ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
| <span >{{test}}</span>
| </template>
Ok, I got this to work. Couple of things that might help.
I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.
Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.
The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.
Hope this helps someone.
karma.conf.js:
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack']
},
webpack: {
resolve: {
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
vue: {
buble: {
objectAssign: 'Object.assign'
}
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
},
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' },
]
},
});
};
I ran into the exact same problem. The accepted answer did not fully work for me. The following solved my issue:
Install relevant loaders for webpack:
npm install --save-dev vue-loader file-loader url-loader
Create webpack config file (note the format). The accepted answer produced errors citing invalid format of the webpack.config.js file. At least with me it did.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{ loader: 'vue-loader' }
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
}
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
]
}
}
karma.conf.js
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/*.js', watched: false},
{pattern: 'tests/**/*.js', watched: false}
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
Then run karma start and everything should work.

jsx react debugger not matching despite webpack source maps

I'm learning React and JSX and using webpack to compile but when I throw in 'debugger' into my component, the line isn't matched when I'm in Chrome Dev Tools' Sources tab (in general the sources doesn't reflect what I have in my app.jsx file at all). The React tab doesn't really load up either. Below is my webpack.config:
module.exports = {
context: __dirname,
entry: "./api_assignment.jsx",
output: {
path: "./",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react']
}
}
]
},
devtool: 'source-map',
resolve: {
extensions: ["", ".js", ".jsx"]
}
};
//Webpack screenshot
If you are loading your html from local file and not webpack server, you need to enable React Developer Tools extension option "Allow access to file URLs".

Resources