Webpack Issue with * in export statement - javascript

I'm attempting to package with webpack. However, I am receiving a Module parse failed: Unexpected token error. It points to a node module, which has a export statement using an astrisk.
export * as example from "exampleModule";
How can I avoid webpack throwing the error when building?
I'm using babel 7.11.5 and have plugin-proposal-export-namespace-from in my babel config plugins.
My babel.config.js is as follows:
/* eslint global-require: off, import/no-extraneous-dependencies: off */
const developmentEnvironments = ['development', 'test'];
const developmentPlugins = [require('react-hot-loader/babel')];
const productionPlugins = [
require('babel-plugin-dev-expression'),
// babel-preset-react-optimize
require('#babel/plugin-transform-react-constant-elements'),
require('#babel/plugin-transform-react-inline-elements'),
require('babel-plugin-transform-react-remove-prop-types'),
];
module.exports = (api) => {
// See docs about api at https://babeljs.io/docs/en/config-files#apicache
const development = api.env(developmentEnvironments);
return {
presets: [
// #babel/preset-env will automatically target our browserslist targets
require('#babel/preset-env'),
require('#babel/preset-typescript'),
[require('#babel/preset-react'), { development }],
],
plugins: [
// Stage 0
require('#babel/plugin-proposal-function-bind'),
// Stage 1
require('#babel/plugin-proposal-export-default-from'),
require('#babel/plugin-proposal-logical-assignment-operators'),
[require('#babel/plugin-proposal-optional-chaining'), { loose: false }],
[
require('#babel/plugin-proposal-pipeline-operator'),
{ proposal: 'minimal' },
],
[
require('#babel/plugin-proposal-nullish-coalescing-operator'),
{ loose: false },
],
require('#babel/plugin-proposal-do-expressions'),
// Stage 2
[require('#babel/plugin-proposal-decorators'), { legacy: true }],
require('#babel/plugin-proposal-function-sent'),
require('#babel/plugin-proposal-export-namespace-from'),
require('#babel/plugin-proposal-numeric-separator'),
require('#babel/plugin-proposal-throw-expressions'),
// Stage 3
require('#babel/plugin-syntax-dynamic-import'),
require('#babel/plugin-syntax-import-meta'),
[require('#babel/plugin-proposal-class-properties'), { loose: true }],
require('#babel/plugin-proposal-json-strings'),
...(development ? developmentPlugins : productionPlugins),
],
};
};

Related

Multi-profile (ESM format) Cucumber configuration file not quite working

I have the following configuration file for Cucumber:
const common = {
// ...common settings here
};
module.exports = {
ci: {
...common,
format: [
"progress",
],
},
default: {
...common,
format: [
"progress-bar",
],
},
};
This works flawlessly. I can specify any of the defined profiles, etc. I'm looking migrate, if possible, the same configuration file into ESM format, but I just don't quite understand how to make the default profile work. If I do:
export default {
ci: { /* ... */ },
default: { /* ... */ },
};
...and place "type": "module" in package.json, it stops working and the configuration is not understood anymore.
Can anyone spot what's the catch there? Would be great a small explanation if this can be done :)
I was initially confused by the default keyword ;)
This is a working (ESM) configuration with multiple profiles:
const common = {
/* ... */
};
export const ci = {
...common,
format: [
"progress",
],
};
export default {
...common,
format: [
"progress-bar",
],
};

Rails Webpack Issue with quill.js

I hope someone can help me.
I have Quill.js in my app and it seems to be causing a bug for some reason. It is causing the css and styling to not load and I see the following error in the console:
In my postcss.config.js looks like the following:
let environment = {
plugins: [
require('tailwindcss')("./app/javascript/stylesheets/tailwind.config.js"),
require('autoprefixer'),
// require("micromodal"),
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('quill'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}),
]
}
// Only run PurgeCSS in production/staging (you can also add staging here)
if (process.env.RAILS_ENV === "production" || process.env.RAILS_ENV === "staging") {
environment.plugins.push(
require('#fullhuman/postcss-purgecss')({
content: [
'./app/**/*.html.erb',
'./app/**/*.js.erb',
'./app/helpers/**/*.rb',
'./app/javascript/**/*.js',
'./app/javascript/**/*.vue',
'./app/javascript/**/*.jsx',
'./app/javascript/**/*.css',
'./app/javascript/**/*.scss',
'./app/stylesheets/**/*.css',
'./app/stylesheets/**/*.scss',
],
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
})
)
}
module.exports = environment
// uncomment this for checking for development
// module.exports = {
// plugins: [
// require('tailwindcss')("./app/javascript/stylesheets/tailwind.config.js"),
// require('autoprefixer'),
// require('postcss-import'),
// require('postcss-flexbugs-fixes'),
// require('postcss-preset-env')({
// autoprefixer: {
// flexbox: 'no-2009'
// },
// stage: 3
// }),
// require('#fullhuman/postcss-purgecss')({
// content: [
// './app/**/*.html.erb',
// './app/helpers/**/*.rb',
// './app/javascript/**/*.js',
// './app/javascript/**/*.vue',
// './app/javascript/**/*.jsx',
// './app/stylesheets/**/*.css',
// './app/stylesheets/**/*.scss',
// ],
// defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
// })
// ]
// }
I deleted the Gemfile.lock and also ran rake assets:precompile.
Do you know what I am missing or doing wrong?
Any help would be greatly appriciated.

Vue 3 - How to add Polyfills to ChainWebpack

Using Vue 3, how do I add path-browserify to vue.config.js?
module.exports = {
chainWebpack: config => {}
}
I am receiving the following error when compiling:
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
Webpack 5 removed some things that Webpack 4 included in the bundle.
To get it all back in a vue3 app you can use the polyfill plugin.
From a vanilla create-vue-app with babel:
> npm i node-polyfill-webpack-plugin
babel.config.js
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
]
}
vue.config.js
const { defineConfig } = require("#vue/cli-service");
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
optimization: {
splitChunks: {
chunks: "all",
},
},
},
});
With #Zack's help, using chainWebpack:
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
module.exports = {
chainWebpack: config => {
config.plugin('polyfills').use(NodePolyfillPlugin)
},
}

Uncaught ReferenceError: process is not defined when working with VuePress

I'm trying to create documentation for my component library, and I'm running into Uncaught ReferenceError: process is not defined when I try to get VuePress running in development. I'm not sure how to resolve this.
This library is scaffolded using vue-sfc-rollup
// enhanceApp.js
import ComponentLibrary from './../../src/entry.js'
export default ({ Vue, options, router, siteData }) => {
Vue.use(ComponentLibrary)
}
// entry.js
// Import vue components
import * as components from '#/lib-components/index';
// install function executed by Vue.use()
const install = function installVueCharge(Vue) {
if (install.installed) return;
install.installed = true;
Object.entries(components).forEach(([componentName, component]) => {
Vue.component(componentName, component);
});
};
// Create module definition for Vue.use()
const plugin = {
install,
};
// To auto-install on non-es builds, when vue is found
// eslint-disable-next-line no-redeclare
/* global window, global */
if ('false' === process.env.ES_BUILD) {
let GlobalVue = null;
if (typeof window !== 'undefined') {
GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
}
// Default export is library as a whole, registered via Vue.use()
export default plugin;
// To allow individual component use, export components
// each can be registered via Vue.component()
export * from '#/lib-components/index';
Edit: I've added my rollup.config.js as this is where process.env.ES_BUILD is defined.
// rollup.config.js
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
import alias from '#rollup/plugin-alias';
import commonjs from '#rollup/plugin-commonjs';
import replace from '#rollup/plugin-replace';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import minimist from 'minimist';
// Get browserslist config and remove ie from es build targets
const esbrowserslist = fs.readFileSync('./.browserslistrc')
.toString()
.split('\n')
.filter((entry) => entry && entry.substring(0, 2) !== 'ie');
const argv = minimist(process.argv.slice(2));
const projectRoot = path.resolve(__dirname, '..');
const baseConfig = {
input: 'src/entry.js',
plugins: {
preVue: [
alias({
resolve: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
entries: {
'#': path.resolve(projectRoot, 'src'),
},
}),
],
replace: {
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.ES_BUILD': JSON.stringify('false'),
},
vue: {
css: true,
template: {
isProduction: true,
},
},
babel: {
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
},
},
};
// ESM/UMD/IIFE shared settings: externals
// Refer to https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
const external = [
// list external dependencies, exactly the way it is written in the import statement.
// eg. 'jquery'
'vue',
];
// UMD/IIFE shared settings: output.globals
// Refer to https://rollupjs.org/guide/en#output-globals for details
const globals = {
// Provide global variable names to replace your external imports
// eg. jquery: '$'
vue: 'Vue',
};
// Customize configs for individual targets
const buildFormats = [];
if (!argv.format || argv.format === 'es') {
const esConfig = {
...baseConfig,
external,
output: {
file: 'dist/vue-charge.esm.js',
format: 'esm',
exports: 'named',
},
plugins: [
replace({
...baseConfig.plugins.replace,
'process.env.ES_BUILD': JSON.stringify('true'),
}),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
babel({
...baseConfig.plugins.babel,
presets: [
[
'#babel/preset-env',
{
targets: esbrowserslist,
},
],
],
}),
commonjs(),
],
};
buildFormats.push(esConfig);
}
if (!argv.format || argv.format === 'cjs') {
const umdConfig = {
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-charge.ssr.js',
format: 'cjs',
name: 'VueCharge',
exports: 'named',
globals,
},
plugins: [
replace(baseConfig.plugins.replace),
...baseConfig.plugins.preVue,
vue({
...baseConfig.plugins.vue,
template: {
...baseConfig.plugins.vue.template,
optimizeSSR: true,
},
}),
babel(baseConfig.plugins.babel),
commonjs(),
],
};
buildFormats.push(umdConfig);
}
if (!argv.format || argv.format === 'iife') {
const unpkgConfig = {
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-charge.min.js',
format: 'iife',
name: 'VueCharge',
exports: 'named',
globals,
},
plugins: [
replace(baseConfig.plugins.replace),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
babel(baseConfig.plugins.babel),
commonjs(),
terser({
output: {
ecma: 5,
},
}),
],
};
buildFormats.push(unpkgConfig);
}
// Export config
export default buildFormats;
process.env is removed, you can use import.meta.env instead.
https://github.com/vitejs/vite/commit/8ad7ecd1029bdc0b47e55877db10ac630829c7e5

How can I replace files at compile time using webpack?

I have a project with miltiple configuration. The first config is config.dev.js file that contains some development configiration. I using it in development mode. The second config is config.js file. I using it in production mode.
In the code I using imports:
import * as config from './config.js';
I want to use the first config file in development and the second to production whithout rewriting all of the imports. How can I replace this config depending on the build mode?
This is an old question but I've recently stumbled across the same issue and webpack.NormalModuleReplacementPlugin doesn't seem to work anymore (or at least not in my case, where I used JSON files as config). Instead I found another solution using alias:
const path = require("path");
modules.export = {
...
resolve: {
...
alias: {
[path.resolve(__dirname, "src/conf/config.json")]:
path.resolve(__dirname, "src/conf/config.prod.json")
}
}
...
}
I realize this is an old post, but this is one of the first results on Google, so I thought a better answer would be good.
Webpack has a built in "Normal Module Replacement Plugin".
plugins: [
new webpack.NormalModuleReplacementPlugin(
/some\/path\/config\.development\.js/,
'./config.production.js'
)
]
For my use, I put the env file in a variable Here is an example:
let envFilePath = './environment.dev.js';
if (env === 'production') {
envFilePath = './environment.prod.js';
} else if (env === 'staging') {
envFilePath = './environment.stg.js';
}
module.exports = {
// other webpack stuff
....
plugins:[
new webpack.NormalModuleReplacementPlugin(
/src\/environment\/environment\.js/,
envFilePath
),
...
]
}
You can use webpack file-replace-loader
https://www.npmjs.com/package/file-replace-loader
Example:
//webpack.config.js
const resolve = require('path').resolve;
module.exports = {
//...
module: {
rules: [{
test: /\.config\.js$/,
loader: 'file-replace-loader',
options: {
condition: process.env.NODE_ENV === 'development',
replacement: resolve('./config.dev.js'),
async: true,
}
}]
}
}
I wanted to imitate the Angular fileReplacements syntax so I used a config.json like Angular's and if the configuration key matches the env I pass to webpack, loop through the replacements and create several Webpack module rules.
It's not the most elegant thing ever but this is what I ended up with:
// config.json
{
"title": "Some Title",
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
},
"lan": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lan.ts"
}
]
}
}
}
// webpack.config.js
const appConfig = require('./config.json');
module.exports = (env, argv) => {
// env.build is like `ng build --prod` as `webpack --env.build=production`
const configuration = appConfig.configurations[env.build];
const fileReplacements = [];
// Safety Check
if(configuration && configuration.fileReplacements) {
// Iterate through replacements
for(const replacement of configuration.fileReplacements) {
// create Webpack module rule
const replace = {
test: path.resolve(replacement.replace),
loader: 'file-replace-loader',
options: {
replacement: path.resolve(replacement.with),
async: true
}
}
fileReplacements.push(replace);
}
}
return {
mode: //...
entry: //...
module: {
rules: [
{
//...
},
// Unpack anywhere here
...fileReplacements
]
}
}
}
This way you don't have to keep messing with webpack and regex tests, just add to the array in config.json
You can also use babel-loader like this:
//webpack.config.js
const resolve = require('path').resolve;
module.exports = {
//...
module: {
strictExportPresence: true,
rules: [{
test: /\.config\.js$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
plugins: [
[
"module-resolver",
{
resolvePath(sourcePath, currentFile, opts) {
if(process.env.NODE_ENV === 'development') {
return sourcePath.substr(0, sourcePath.lastIndexOf('/')) + '/config.dev.js';
} else {
return sourcePath;
}
}
}
]
]
}
}]
}
}
This way you can even define complex algorithms to determine which file you wanna use.
Another way is to use Webpack.DefinePlugin. Especially useful if you have a tiny code block that you want to be included conditionally.
Example follows:
// webpack.conf.js
// Code block that should be inserted or left blank
const ServiceWorkerReg = `window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});`
appConfig = {
plugins: [
new webpack.DefinePlugin({
__SERVICE_WORKER_REG: isDev ? '' : ServiceWorkerReg,
}),
]
...
}
// Some module index.js
__SERVICE_WORKER_REG
... // other non conditional code

Categories