My end goal here is to use gg=G to autoindent all of my JS code compliant to an eslintrc.js file.
So, currently I have syntastic and vim-javascript looking at my JS code with the following in my .vimrc
let g:syntastic_javascript_checkers=["eslint"]
Lets say that I have some decent JS like the following
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PATHS = {
app : path.join(__dirname, 'app'),
build : path.join(__dirname, 'build'),
};
const commonConfig = {
entry : {
app : PATHS.app,
},
output : {
path : PATHS.build,
filename : '[name].js',
},
plugins : [
new HtmlWebpackPlugin({
title : 'Webpack Demo',
}),
],
};
The gg=G (normal mode) command mutilates the above into the following.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PATHS = {
app : path.join(__dirname, 'app'),
build : path.join(__dirname, 'build'),
};
const commonConfig = {
entry : {
app : PATHS.app,
},
output : {
path : PATHS.build,
filename : '[name].js',
},
plugins : [
new HtmlWebpackPlugin({
title : 'Webpack Demo',
}),
],
};
Which is not cool.
Btw, vim-js-indent and vim-jsx-improve didn't do anything either.
Any help is very welcome, many thanks are in advance.
Your "not cool" example is the result of the "generic" indenting you get when Vim didn't recognize your buffer as JavaScript and/or didn't apply JavaScript-specific indentation rules.
That code is indented correctly with this minimal setup:
$ vim -Nu NONE --cmd 'filetype indent on' filename.js
which:
detects that your buffer contains JavaScript,
applies JavaScript-specific indentation rules.
To ensure proper indenting, you must add this line to your vimrc:
filetype indent on
Related
I am building custom gutenberg blocks using npm, webpack and #wordpress/scripts. Everything was fine until I tried to use block.json file. To use block.json file I need block.asset.php file in the build directory because that's the way WordPress core is coded... (https://github.com/WordPress/gutenberg/issues/40447)
And now my problem is that running npm run build does not generate .asset.php file and I do not know why. When I register blocks using wp_enqueue_script or when I manually create an empty .asset.php it works fine.
My webpack.config.js now looks like this:
const defaultConfig = require("#wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
...defaultConfig,
entry: {
'cgbms-section-block': './src/section-block.js',
'cgbms-article-block': './src/article-block.js',
'cgbms-article-header-block': './src/article-header-block.js',
'cgbms-category-block': './src/category-block.js',
'cgbms-category-block-edit': './src/category-block-edit.js',
'cgbms-card-block': './src/card-block.js',
'style-front': './src/css/style-front.scss',
'style-editor': './src/css/style-editor.scss',
},
output: {
path: path.join(__dirname, './build/'),
filename: './blocks/[name].js'
},
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
]
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/[name].css'
})
],
externals: {
'#wordpress/blocks': 'wp.blocks',
'#wordpress/block-editor': 'wp.blockEditor'
},
}
Okay so solution is actually really simple.
I think I had to import default plugins config:
...defaultConfig.plugins
So my whole webpack.config.js is now:
const defaultConfig = require("#wordpress/scripts/config/webpack.config");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require('path');
module.exports = {
...defaultConfig,
entry: {
'cgbms-section-block': './src/section-block.js',
'cgbms-article-block': './src/article-block.js',
'cgbms-article-header-block': './src/article-header-block.js',
'cgbms-category-block': './src/category-block.js',
'cgbms-category-block-edit': './src/category-block-edit.js',
'cgbms-card-block': './src/card-block.js',
'style-front': './src/css/style-front.scss',
'style-editor': './src/css/style-editor.scss',
},
output: {
path: path.join(__dirname, './build/'),
filename: './blocks/[name].js'
},
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
]
},
plugins: [
...defaultConfig.plugins,
new MiniCssExtractPlugin({
filename: './css/[name].css'
})
]
}
as you can see I also removed externals block.
I am trying to bundle my JS files through Webpack (version 5.x) but it is not bundling order-wise. Here is my configuration file:
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "production",
entry: [
"./src/assets/js/plugins/jQuery.js",
"./src/assets/js/plugins/mdb.js",
"./src/assets/js/plugins/aos.js",
"./src/assets/js/main.js",
],
output: {
filename: "assets/js/[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
]
};
I am expecting in the bundle file orderwise like jQuery.js, mdb.js, aos.js and main.js that I added in the entry. Please help me find the issue and a better way to buddle the JS files.
Thank You
I have divided my configuration in to two production and development mode and merging them using webpack-merge.
Whenever i try to build or run the code it gives me you may need an appropriate loader error even though i have define loader for the jsx or js files.
Common Config File code is here...
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
module.exports = {
entry : "./src/index.js",
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
{
test: /.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
Production Config Code is
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
Development Config Code
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
index.js code
import "./assets/scss/main.scss";
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return <h1>Hello</h1>
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
.babelrc code
{
"presets": ["env", "react","#babel/preset-env"],
"plugins": [
"transform-class-properties"
]
}
You will need to call merge on both your files, merging common with the object specified for each case:
// webpack.prod.js
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
// webpack.dev.js
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
That error occurs because your JSX is not being compiled to JavaScript.
The test in your config file that handles this is:
test: /.(js|jsx)$/,
loader: 'babel-loader',
I see that you've imported "webpack-merge" but it does not appear that you're using it (at least in the code that is displayed in your question).So it seems like you're not merging the disparate config files in the way you're expecting (or maybe at all).
Instead of splitting your config into multiple files, usually [from what I've seen] developers prefer to use one file with some logic in it based on an environmental variable: https://webpack.js.org/guides/environment-variables/
process.env.NODE_ENV === 'dev' ? doDevStuff : doProdStuff
I am currently starting to use webpack for my website and I have a question.
I currently have a html page that includes my javascript bundle and has some onclick functions in buttons embedded in the html. I would like to keep the functionality of these buttons and the onclick, but currently I have not found a way to do this. Obviously, if I try to minify the javascript functions, the name of the function would change and it won't work.
Here's an example, where the bundle produced by webpack is included in the html file:
<button onclick="foo("bar")">test</button> and currently foo is undefined.
I have tried using html webpack plugin without success.
Is there any way to do this?
Yes you can get to the function but you will still have to modify the code slightly - onClick.
webpack
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin');
module.exports = (env, argv) => {
return {
devtool: argv.mode === 'production' ? 'none' : 'source-map',
mode: argv.mode === 'production' ? 'production' : 'development',
entry: {
MYSCRIPT: './sources/script.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: './[name].js',
library: '[name]',
libraryTarget: 'var',
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}, ]
},
plugins: [
new CleanWebpackPlugin({
verbose: true
}),
new HtmlWebPackPlugin({
filename: 'index.html',
template: './sources/index.html'
})
]
}
}
The most important part is the name entry and outputs.
You must also export each function.
JS
export function test(type) {
alert(type);
}
And we can get to the function this way.
HTML
<a onClick="MYSCRIPT.test('bar')">click</a>
You can find the whole devising example here.
I want to create multiple entry points for a website, which is pretty easily done in Webpack using an object for the entry property, like here.
But as the site grows (and it inevitably will) having to add each entry point seems cumbersome and prone to error. So I'd like to simply point at a directory and say "here are all the entry points."
So I've cooked this up:
var path = require('path');
var fs = require('fs');
var entryDir = path.resolve(__dirname, '../source/js');
var entries = fs.readdirSync(entryDir);
var entryMap = {};
entries.forEach(function(entry){
var stat = fs.statSync(entryDir + '/' + entry);
if (stat && !stat.isDirectory()) {
var name = entry.substr(0, entry.length -1);
entryMap[name] = entryDir + '/' + entry;
}
});
module.exports = {
entry: entryMap,
output: {
path: path.resolve(__dirname, '../static/js'),
filename: "[name]"
},
...
This works fine, but is there a feature or configuration option in Webpack that would handle this for me?
I think glob is the right way to go here (AFAIK webpack wont do this for you). This is what I ended up with, it will find all files in a directory and create an entry with a name matching the file:
var glob = require('glob');
var path = require('path');
module.exports = {
entry: glob.sync('../source/js/**.js').reduce(function(obj, el){
obj[path.parse(el).name] = el;
return obj
},{}),
output: {
path: path.resolve(__dirname, '../static/js'),
filename: "[name]"
},
...
adapt the search path to meet your specific needs. It might also be useful to pass in {cwd: someRoot} as the second argument to sync if you have a special scripts directory which will make this the new root of relative path searches.
In my opinion, only a little Node skill is needed, and it doesn't have to be that complicated.
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
const fileNames = fs.readdirSync('./src').reduce((acc, v) => ({ ...acc, [v]: `./src/${v}` }), {});
const config = {
entry: fileNames,
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name]',
},
};
module.exports = config;
I have used Glob for this.
var path = require('path');
var glob = require('glob');
module.exports = {
entry: { 'app' : glob.sync('./scripts/**/*.ts*') },
output: {
path: path.join(__dirname, '/wwwroot/dist'),
filename: '[name].bundle.js',
sourceMapFilename: '[name].map'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
}
]
},
resolve: {
extensions: [".ts", ".js"]
}
};