Disable webpack's file watching for vim swp files - vim

Everytime I open file with vim, webpack detects changes and recompiles the code. Vim creates temporary files like .test.txt.swp which makes webpack believe something has changed in the project.
Disabling swp file creation helped, but I would like to remain safe with swp files and not get distracted with browser reloading the page too often, nor with unnecessary code compilation.
How to make webpack know it should not react for .*.swp files changes?
EDIT:
It is actually webpack-dev-server which reacts to new vim swap files detected. And it does it only when there are specific entries in source files that are about to be compiled. Examples are from importing angular2, but not only it:
import '#angular/core';
import '#angular/common';

I know nothing about "webpack", but you can tell Vim to store swap files in a single directory instead of the current directory with the 'dir' setting. I use this in my vimrc:
set dir=$HOME/.vim/tmp/swap
if !isdirectory(&dir) | call mkdir(&dir, 'p', 0700) | endif
This will also fix issues with other tools, as well as "dangling swap files", swap files in VCS systems, etc.
If you want to ignore Vim swap files in tools (such as webpack) then remember that just ignoring .swp is not enough; Vim may also create swap files with extensions such as .swo, .swn, etc.

You can exclude files based on a pattern:
module: {
loaders: [
{
// existing loader config
exclude: /\.swp$/,
},
]
}
You shouldn't be bundling everything by default, though; use a loader test to only bundle .js files (or whatever you explicitly needs; .jsx, .css, etc.). Something like this, for example:
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: [/node_modules/, 'test/', /\.swp$/],
query: {
presets: ['es2015', 'react']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
]
}

The answer for me was the following change in the webpack configuration
<webpackConfObject>.devServer.watchOptions = {
ignored: /\.sw.$/
};
The exclude attribute of modules does not apply to the file watcher that triggers an event to reload the page on the webpack dev server, but you can ignore files that match a pattern.

Related

Nuxt/webpack build error- Module parse failed: Unexpected character '#'

I'm completely new to Nuxt and Webpack, so I'm not sure quite what details I should include here, but I'm working on a VueJS project and I can't stop getting this error when I try to run a build:
ERROR in ./node_modules/node-fetch-native/dist/index.cjs 69:2
Module parse failed: Unexpected character '#' (69:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| */
| class BlobDataItem {
> #path
| #start
|
# ./node_modules/node-fetch-native/lib/index.cjs 1:18-46
# ./.nuxt/server.js
# multi ./node_modules/#nuxt/components/lib/installComponents.js ./.nuxt/server.js
This error is coming from a dependency so I don't want to edit the code in the file as that isn't a great long-term solution. I've tried adding this to my webpack.config file:
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
... but still nothing. I've also had some problems with package dependencies, if that has anything to do with it. Let me know if there are other details I need to include. Thanks in advance!
Because of an unusual # character at line 69, column 2, the webpack module bundler appears to be having trouble parsing the code in the node-fetch-native package, according to the error notice you provided.
You can try adding a JavaScript file loader that can handle the syntax used in the node-fetch-native package to your webpack setup in an attempt to fix this problem. You can accomplish this by including the following rule in your module. 
in your module.rules:
{
test: /\.m?js$/,
resolve: {
fullySpecified: false
}
}
I found the fix! Apparently this is an error with the a Nuxt update and we have to wait for a fix, but for now you can do this:
Go into nuxt.config.js
Find build > standalone (in mine it was at the very bottom)
Change it from true to false like this:
build: {
standalone: false
}

Configure Rollup to add file extensions into import/require statements

I have a hybrid cjs/esm Node package written in Typescript.
It consists of, let's say, two files - core.ts and extra.ts and I want to keep them separate. extra.ts imports core.ts (literally import { ... } from './core';) and they are separate entry points of the package. Clients import either only core.ts or both.
Rollup makes it easy to have build steps for multiple entry points, for multiple output formats, and all seemed fine.
But now I ran into an issue:
Let's say I have example.mjs or example.cjs where I import or require my-package and my-package/extra entry points.
That doesn't work. Error messages are slightly different but meaning is the same - ./core module can not be found when reading extra.mjs/cjs.
extra.cjs built by Rollup contains the line var core = require('./core');
extra.mjs built by Rollup contains the line import { ... } from './core';
By default, Node 12 does not guess file extensions (I'm not questioning this).
I have to call it as node --experimental-modules --es-module-specifier-resolution=node ./example.mjs to make it work. This is unsatisfactory solution. I need example.mjs to be runnable without additional flags.
It appears to me that file extensions can and should be added to import/require statements in compiled cjs/mjs files to make it work according to the spec.
Although, since I have different build steps in Rollup config for both files and external: ['./core'] in the options for extra.ts, for Rollup they are totally unrelated. And Rollup will just bundle them into a single file otherwise, which is not what I need either.
So the question:
Is there a plugin or a configuration option to make Rollup produce files with correct local imports (file extensions added to local imports according to the format)?
What would be the best way to add an extra step to the building process to patch imports if there is no existing solution?
Maybe there a different bundler that might work for the same task?
Got a satisfactory solution.
output.preserveModules option keeps all files separate while building them in one pass (can be limiting in some aspects though).
output.entryFileNames option allows to specify file extensions. (It won't work with modules considered external, can't use it without preserveModules.)
I can build only extra.ts as it imports every other file. But I have to be mindful of tree shaking when building like this - need to retain all exports of core.ts.
export default [
{
external: [],
input: 'src/extra.ts',
treeshake: false,
plugins: [
typescript(),
cleanup({ extensions: ['ts'] })
],
output: [
{
dir: 'lib',
format: 'es',
preserveModules: true,
entryFileNames: '[name].mjs',
},
{
dir: 'lib',
format: 'cjs',
preserveModules: true,
entryFileNames: '[name].cjs',
},
],
},
];
One step back is that I get another output file for another ts file imported by core.ts and extra.ts. I think I can live with that.
Ideal solution would require to monkey-patch output files with sed-like tool after the build in my initial configuration.

How to bundle node module CSS into a vscode extension

My Visual Studio Code extension uses the node module highlight.js which comes with a folder full of CSS files. These provide colour schemes for syntax colouring. It has become necessary to bundle some of the CSS files.
It's about bundling an asset
The objective is to bundle a CSS file and at run-time access the file content as a string. If that can be achieved without an import statement that would be perfect. Normally, how exactly one accesses the content of the bundled file would be a separate question, but I have a feeling that content retrieval and how one should go about bundling the asset are closely entwined.
I freely admit to having a weak understanding of WebPack.
The story so far
The bundler is specified in package.json as "webpack": "^5.4.0" but I don't know how to ascertain what is actually present. It is conceivable that there is something wrong with my setup: when I try to run webpack --version on a command prompt in the project folder, it responds
CLI for webpack must be installed.
webpack-cli (https://github.com/webpack/webpack-cli)
We will use "npm" to install the CLI via "npm install -D webpack-cli".
Do you want to install 'webpack-cli' (yes/no):
The first time this happened I responded yes. After a flurry of installation and another try the same thing happened. However, vsce package has no trouble using webpack for a production build and pressing F5 to debug successfully puts together a development build in a dist folder with an unminified file I can examine (which is how I know the file mentioned below is being bundled).
Moving on from there I've modified webpack.config.js like so
//#ts-check
'use strict';
const path = require('path');
/**#type {import('webpack').Configuration}*/
const config = {
target: 'node', // vscode extensions run in a Node.js-context -> https://webpack.js.org/configuration/node/
entry: './src/extension.ts', // the entry point of this extension, -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: 'commonjs2',
devtoolModuleFilenameTemplate: '../[resource-path]'
},
devtool: 'source-map',
externals: {
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, -> https://webpack.js.org/configuration/externals/
},
resolve: {
// support reading TypeScript and JavaScript files, -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js', '.css']
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
};
module.exports = config;
As you can see there are rules and loaders for CSS.
When I add this import
import "../node_modules/highlight.js/styles/atelier-dune-light.css";
webpack happily builds the bundle and when I inspect it I can find the bundled CSS.
However, when I try to load the extension in the extension debug host, it fails to load, with this message.
Activating extension 'pdconsec.vscode-print' failed: document is not defined.
Enabling break on caught exceptions reveals this rather surprising exception.
Exception has occurred: Error: Cannot find module 'supports-color'
Require stack:
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\node_modules.asar\get-uri\node_modules\debug\src\node.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\node_modules.asar\get-uri\node_modules\debug\src\index.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\node_modules.asar\get-uri\dist\index.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\node_modules.asar\vscode-proxy-agent\out\agent.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\node_modules.asar\vscode-proxy-agent\out\index.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\out\bootstrap-amd.js
- c:\Users\Peter\AppData\Local\Programs\Microsoft VS Code\resources\app\out\bootstrap-fork.js
OK, so activation failed because the loader barfed. But WTF does importing CSS have to do with support-color?
Remove the import and it runs just fine. I really don't know how to respond to this; it's not clear to me why a demand for a stylesheet should cause that error. At this point I look to others for guidance and advice.
Remove style-loader from webpack.config.js to fix the error.
Pull the CSS as a string like this. Note the abbreviated path.
const cssPath: string = "highlight.js/styles/atelier-dune-light.css";
const theCss: string = require(cssPath).default.toString();
You do not need the import statement, the use of require will cause Webpack to bundle the files, but you still have to remove style-loader to avoid the loader error.

Babel not transpiling ES6 module in node_modules despite proper exclude

In a react project I used react-boilerplate but had private modules to include in the frontend that needed transpiling. In order for babel to transpile those I set exclude to the following function in the webpack config that relates to babel:
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with Babel
// eslint-disable-next-line object-shorthand, func-names
exclude: function (modulePath) {
return /node_modules/.test(modulePath) &&
!/node_modules\/#trade-quorum\/tq-helpers/.test(modulePath);
},
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
And it worked perfectly.
Now I used that same trick in a different project but this time, in the resulting bundle tq-helpers is included but not transpiled into ES5 - the ES6 code is directly in the bundle and the build raises an error (more specifically UglifyJS).
There must be a reason around the dependencies to this package that are not the same in the two projects but hard to find. I was wondering whether there is a way to debug in details what babel does for a specific package in order to find the reason.
Thanks you for your help,
Best,
Didier

What is the "Node way" to split code across multiple files?

I am currently working on a NodeJS/Typescript project, it is a HTML5 client with a NodeJS server that communicates via web-sockets. Coming from a C# background, I like to keep my code separated into different files for different things, including a shared file for objects to be serialised and de-serialised for sending/receiving data in an organised & well defined manner.
Currently at the server side, i have the build options set to compile it down to a single JavaScript file and I have that as my startup script, but I believe this to be a messy solution to my problem. To fix an issue with the order of the output file, i have also had to put an ordered list of references to the various TypeScript files at the top of my "main" typescript file.
This seems like the complete wrong way to do it, is it possible to still separate out different Typescript(/Javascript) files so that different areas of logic are in a dedicated place, whilst still being able to share a file be between my HTML client & my NodeJS server, or is this just a workaround i am going to have to learn to live with?
You could use webpack module bundler to avoid your ordered list of references. Webpack takes care of all dependency resolution and referencing. To share code between server and client, you could seperate it out in a common module/package and import it on both sides.
I use webpack to compile my Typescript code to ES6 code for the server code and with an extra build step (babel.io) to browser compatible code.
The following example configuration shows the usage of webpack with Typescript:
var path = require('path');
module.exports = {
entry: {
app: [ path.join(__dirname, './src/App.ts') ]
},
devtool: 'source-map',
output: {
path: path.join(__dirname, './build'),
filename: 'js/bundle.[name].js'
},
module: {
loaders: [{
// The loader that handles ts and tsx files. These are compiled
// with the ts-loader and the output is then passed through to the
// babel-loader. The babel-loader uses the es2015 and react presets
// in order that jsx and es6 are processed.
test: /\.ts(x?)$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=es2015!ts-loader'
}, {
// The loader that handles any js files presented alone.
// It passes these to the babel-loader which (again) uses the es2015
// and react presets.
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015']
}
}]
},
resolve: {
extensions: ['', '.ts', '.tsx', '.js'],
modulesDirectories: ['node_modules', 'src', 'lib']
}
};

Resources