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
Related
I'm building an Electron application with these versions:
electron - 22.0.0
electron-builder - 23.6.0
async npm package - 3.2.4
This is my electron-builder configuration file:
module.exports = {
appId: 'com.electron.balbdldldld',
productName: 'Hblalalala',
files: ['./dist'],
directories: {
buildResources: 'resources',
output: 'release',
},
asarUnpack: '**\\*.{node,dll,exe}',
extraResources: ['build/', 'resources/'],
win: {
target: ['nsis'],
sign: 'scripts/sign.js',
signingHashAlgorithms: ['sha256'],
},
nsis: {
guid: 'bbbbbbb',
include: 'build/installer.nsh',
artifactName: 'blalflflvl.${ext}',
runAfterFinish: false,
createStartMenuShortcut: false,
createDesktopShortcut: false,
},
};
I build the renderer process using vite:
import path from 'path';
import react from '#vitejs/plugin-react';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import sassDts from 'vite-plugin-sass-dts';
import { version } from './package.json';
export default defineConfig(() => ({
root: path.join(__dirname, 'app', 'renderer'),
server: {
port: 4200,
open: true,
},
base: './',
build: { outDir: path.join(__dirname, 'dist') },
plugins: [react(), tsconfigPaths(), sassDts()],
resolve: { alias: { '#/styles': path.join(__dirname, 'app', 'renderer', 'styles') } },
define: {
__PACKAGE_VERSION__: JSON.stringify(version),
},
}));
And I build the main process using webpack:
import path from 'path';
import webpack from 'webpack';
import nodeExternals from 'webpack-node-externals';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin';
/**
* The function returns the OS target for compilation
* #returns the OS target
*/
const getOsTarget = () => {
if (process.platform === 'win32') {
return 'windows';
}
if (process.platform === 'darwin') {
return 'darwin';
}
return null;
};
const osTarget = getOsTarget();
if (osTarget === null) {
console.log('Failed to build, unsupported platform');
process.exit(1);
}
const rootPath = path.join(__dirname, '..');
const applicationCodePath = path.join(rootPath, 'app');
const distPath = path.join(rootPath, 'dist');
const nodeModulesPath = path.join(rootPath, 'node_modules');
const configuration: webpack.Configuration = {
mode: 'production',
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
}),
],
target: 'electron-main',
entry: {
main: path.join(applicationCodePath, 'main', 'main.ts'),
preload: path.join(applicationCodePath, 'preload', 'main.ts'),
},
externals: [nodeExternals({ modulesDir: path.join(rootPath, 'node_modules') })],
output: {
path: distPath,
filename: '[name].js',
library: { type: 'umd' },
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
configFile: path.join(rootPath, 'tsconfig.build.json'),
transpileOnly: true,
},
},
],
},
],
},
resolve: {
extensions: ['.js', '.json', '.ts'],
modules: [applicationCodePath, nodeModulesPath],
plugins: [
new TsconfigPathsPlugin({
configFile: path.join(rootPath, 'tsconfig.build.json'),
extensions: ['.ts'],
}),
],
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
},
plugins: [
new webpack.NormalModuleReplacementPlugin(/\-\[(darwin|windows)\]./, (resource) => {
resource.request = resource.request.replace(/(darwin|windows)/, osTarget);
}),
],
node: {
__dirname: false,
__filename: false,
},
};
export default configuration;
Then I build my complete electron application by running:
Build renderer process code: vite build -c ./vite.config.ts
Build main process code: webpack --config ./webpack/webpack.config.prod.ts
Build electron: electron-builder --config ./electron.build.cjs
Then everything goes fine. When I inspect the results in my release folder I can see this file: ./release/win-unpacked/resources/app.asar. When I unpack it using npx asar unpack app.asar app.unpack I can inspect the app.asar file. Then I can see the following file exists: ./app.unpack/node_modules/async/apply.js. Note that apply.js file. However, when I download the application by using the .exe file, I get a run time error in JS Code:
Uncaught exception:
Error: Cannot find module './apply`
Require Stack:
"........./resources/app.asar/node_modules/async/index.js"
And when I unpack, again with same way, this .../resources/app.asar file, the file indeed does not exist. So why this file is missing while installing the .exe file?
I want this file to exist
I'm writing an electron app with react. I run the developement version using this command:
webpack-dev-server --hot --host 0.0.0.0 --port 4000 --config=./webpack.dev.config.js
Here is the webpack.dev.config.js file
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { spawn } = require('child_process');
const helpers = require('./config/helpers');
// Config directories
const SRC_DIR = path.resolve(__dirname, 'src');
const OUTPUT_DIR = path.resolve(__dirname, 'dist');
// Any directories you will be adding code/files into, need to be added to this array so webpack will pick them up
const defaultInclude = [SRC_DIR];
module.exports = {
entry: SRC_DIR + '/index.js',
output: {
path: OUTPUT_DIR,
publicPath: '/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
include: defaultInclude
},
{
test: /\.jsx?$/,
use: [{ loader: 'babel-loader' }],
include: defaultInclude
},
{
test: /\.(jpe?g|png|gif)$/,
use: [{ loader: 'file-loader?name=img/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [{ loader: 'file-loader?name=font/[name]__[hash:base64:5].[ext]' }],
include: defaultInclude
}
]
},
target: 'electron-renderer',
plugins: [
new HtmlWebpackPlugin({
template: helpers.root('public/index.html'),
inject: 'body'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
devtool: 'cheap-source-map',
devServer: {
contentBase: OUTPUT_DIR,
stats: {
colors: true,
chunks: false,
children: false
},
setup() {
spawn(
'electron',
['.'],
{ shell: true, env: process.env, stdio: 'inherit' }
)
.on('close', code => {
console.error("electron exited with code ", code);
process.exit(0)
})
.on('error', spawnError => console.error(spawnError));
}
}
};
Once the electron browser opens it has the following error in the Dev-Tools console.
Uncaught ReferenceError: require is not defined
at Object.url (index.js:23)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
at Object../node_modules/webpack-dev-server/client/utils/createSocketUrl.js (createSocketUrl.js:4)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
at Object.<anonymous> (client:20)
at Object../node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:4000 (client:176)
at __webpack_require__ (bootstrap:709)
at fn (bootstrap:94)
The place where it claims this is occurring is at index.js:23.
Here is the build version of index.js:
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { ipcRenderer as ipc } from "electron";
import { onUpdate } from "./actions/workerActions";
import { RECEIVED_STATE } from "./actions/types";
import "./assets/css/index.css";
import rootReducer from "./reducers/rootReducer";
import defaultState from "../config/defaultstate"; //Setup redux store
const middleware = [thunk];
const store = createStore(rootReducer, defaultState, applyMiddleware(...middleware));
ipc.on(RECEIVED_STATE, arg => {
console.log("Recieved State: ", arg);
onUpdate(arg)(store.dispatch);
}); // Now we can render our application into it
render(React.createElement(Provider, {
store: store
}, React.createElement(App, null)), document.getElementById("app"));
As you can see require does not appear here and all of the import aside from ipcRender are designed to run client-side, and therefore should not use required. I tried commenting out the ipcRender import but it resulted in the exact same error.
Most puzzlingly of all, I get the exact same error even with the entire index.js file commented out. The console still claiming the block comment contains a reference to require, which is not defined.
If you're using webpack directly then make sure you have the following in the webpack config that targets your renderer code.
// webpack.config.js
...
module.exports = {
...
target: 'web',
...
}
If you're using Vue then you'll need something like the following:
// vue.config.js
...
module.exports = {
...
configureWebpack: {
target: 'web'
},
...
}
Or, in my case I was using vue-cli-plugin-electron-builder and so need the following:
// vue.config.js
...
module.exports = {
...
pluginOptions: {
electronBuilder: {
nodeIntegration: false,
chainWebpackRendererProcess: config => {
config.target('web');
}
}
},
...
}
It turns out that the error is caused by importing electron's ipcRenderer which requires node integration and uses require. The reason that commenting out the import in the index.js didn't fix the error was because it was imported in other files.
I have created configureStore.dev.js file to configure store for my react-redux app. Below is my code for configureStore.dev.js file.
I am getting "require not defined" error for the "const nextRootReducer = require('../reducers').default;".
How can I rewrite this part to solve the issue?
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import StockApp from '../reducers';
import DevTools from '../containers/DevTools';
const createDevStoreWithMiddleware = compose(
applyMiddleware(thunk),
applyMiddleware(createLogger()),
DevTools.instrument()
)(createStore);
export default function configureStore() {
const store = createDevStoreWithMiddleware(StockApp);
// enable webpack hot module replacement for reducers
if (module.hot) {
module.hot.accept('../reducers', () => {
// eslint-disable-next-line
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}
Here is my webpack.config.js:
// We are using node's native package 'path'
// https://nodejs.org/api/path.html
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
// Constant with our paths
const paths = {
DIST: path.resolve(__dirname, 'dist'),
SRC: path.resolve(__dirname, 'src'),
JS: path.resolve(__dirname, 'src/js'),
};
// Webpack configuration
module.exports = {
entry: path.join(paths.JS, 'app.js'),
output: {
path: paths.DIST,
filename: 'app.bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(paths.SRC, 'index.html'),
}),
new ExtractTextPlugin('style.bundle.css'),
],
// We are telling webpack to use "babel-loader" for .js and .jsx files
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
use: 'css-loader',
}),
},
{
test: /\.(png|jpg|gif)$/,
use: [
'file-loader',
],
},
],
},
// Enable importing JS files without specifying their's extenstion -> ADDED IN THIS STEP
//
// So we can write:
// import MyComponent from './my-component';
//
// Instead of:
// import MyComponent from './my-component.jsx';
resolve: {
extensions: ['.js', '.jsx'],
},
target: 'node',
externals: [nodeExternals()],
node: {
console: true,
fs: 'empty',
net: 'empty',
tls: 'empty'
},
// Dev server configuration -> ADDED IN THIS STEP
// Now it uses our "src" folder as a starting point
devServer: {
contentBase: paths.SRC,
},
};
Could anyone please help me solve this issue?
Thank you.
Hoping that you are using Babel 6+, you can replace this code:
const nextRootReducer = require('../reducers').default;
store.replaceReducer(nextRootReducer);
With this:
store.replaceReducer('.default')
No need to require. Hope it helps.
I am trying to upgrade an old framework I built in javascript to es6/module standards and I have a lot of troubles.
One of my current problems is that due to server side rendering my modules are sometime loaded in the node environment and are trying to access the window, causing errors.
Is there a principled way to manage this ?
The main jQuery file has a nice failback if window is undefined and can load in node without a fuss. I am trying to implement this in web-pack by I am stumbling.
This is my current webpack config
// #flow
// import path from 'path'
import webpack from 'webpack'
const WDS_PORT = 7000
const PROD = JSON.parse(process.env.PROD_ENV || '0')
const libraryName = 'experiment'
const outputFile = `${libraryName}${PROD ? '.min' : '.max'}.js`
const plugins = [
new webpack.optimize.OccurrenceOrderPlugin(),
]
const prodPlugins = plugins.concat(new webpack.optimize.UglifyJsPlugin())
// not really working
export default {
entry: './builder.js',
target: 'web',
output: {
path: `${__dirname}/lib`,
filename: outputFile,
library: libraryName,
libraryTarget: 'umd',
umdNamedDefine: true,
},
module: {
loaders: [
{
test: /(\.jsx|\.js)$/,
loader: 'babel-loader',
exclude: /(node_modules|bower_components)/,
},
],
},
devtool: PROD ? false : 'source-map',
resolve: {
extensions: ['.js', '.jsx'],
},
externals: {
chartjs: {
commonjs: 'chartjs',
amd: 'chartjs',
root: 'Chart', // indicates global variable
},
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
jquery: 'jQuery',
mathjs: {
commonjs: 'mathjs',
amd: 'mathjs',
root: 'math', // indicates global variable
},
'experiment-boxes': {
commonjs: 'experiment-boxes',
amd: 'experiment-boxes',
root: 'experimentBoxes', // indicates global variable
},
'experiment-babylon-js': {
commonjs: 'experiment-babylon-js',
amd: 'experiment-babylon-js',
root: 'EBJS', // indicates global variable
},
},
devServer: {
port: WDS_PORT,
hot: true,
},
plugins: PROD ? prodPlugins : plugins,
}
And this is my main entry point builder.js
/* --- Import the framwork --- */
import TaskObject from './src/framework/TaskObject'
import StateManager from './src/framework/StateManager'
import State from './src/framework/State'
import EventData from './src/framework/EventData'
import DataManager from './src/framework/DataManager'
import RessourceManager from './src/framework/RessourceManager'
import {
Array,
String,
diag,
rowSum,
getRow,
matrix,
samplePermutation,
rep,
Deferred,
recurse,
jitter,
delay,
looksLikeAPromise,
mustHaveConstructor,
mustBeDefined,
mandatory,
debuglog,
debugWarn,
debugError,
noop,
} from './src/framework/utilities'
/* add it to the global space in case user want to import in a script tag */
if (typeof window !== 'undefined') {
window.TaskObject = TaskObject
window.StateManager = StateManager
window.State = State
window.EventData = EventData
window.DataManager = DataManager
window.RessourceManager = RessourceManager
window.jitter = jitter
window.delay = delay
window.Deferred = Deferred
}
export {
TaskObject,
StateManager,
State,
EventData,
DataManager,
RessourceManager,
Array,
String,
diag,
rowSum,
getRow,
matrix,
samplePermutation,
rep,
Deferred,
recurse,
jitter,
delay,
looksLikeAPromise,
mustHaveConstructor,
mustBeDefined,
mandatory,
debuglog,
debugWarn,
debugError,
noop,
}
Am I on the right track?
Ok my solution so far, although feels like a hack, protects against require() in node environment.
In the ENTRY FILE of your webpack config check for window being defined.
Here is an example when trying to re-bundle babylonjs which relies heavily on window and would generate an error when required by node:
builder.js
let BABYLON = {}
let OIMO = {}
if (typeof window !== 'undefined') {
BABYLON = require('./src/babylon.2.5.full.max')
OIMO = require('./src/Oimo').OIMO
window.BABYLON = BABYLON
window.OIMO = OIMO
}
module.exports = { BABYLON, OIMO }
webpack.config.babel.js
import path from 'path'
import webpack from 'webpack'
const WDS_PORT = 7000
const PROD = JSON.parse(process.env.PROD_ENV || '0')
const plugins = [
new webpack.optimize.OccurrenceOrderPlugin(),
]
const prodPlugins = plugins.concat(new webpack.optimize.UglifyJsPlugin())
export default {
entry: [
'./builder.js',
],
output: {
filename: PROD ? 'babylon.min.js' : 'babylon.max.js',
path: path.resolve(__dirname, 'lib/'),
publicPath: `http://localhost:${WDS_PORT}/lib/`,
library: 'EBJS',
libraryTarget: 'umd',
umdNamedDefine: true,
},
module: {
rules: [
{ test: /\.(js|jsx)$/, use: 'babel-loader', exclude: /node_modules/ },
],
},
devtool: PROD ? false : 'source-map',
resolve: {
extensions: ['.js', '.jsx'],
},
devServer: {
port: WDS_PORT,
hot: true,
},
plugins: PROD ? prodPlugins : plugins,
}
Testing the bundle in node with a simple file like so:
bundle.test.js
const test = require('./lib/babylon.min.js')
console.log(test)
Will produce in the terminal:
$ node bundle.test.js
{ BABYLON: {}, OIMO: {} }
I'm doing some testing with the latest and greatest webpack 2 version and came across a problem when trying to import jQuery 3.1.1 as a dependency.
I simply used import {$} from 'jquery'; to import but the resulting bundle generated an exception TypeError: __webpack_require__.i(...) is not a function when executed.
Using const $ = require('jquery'); works as expected.
It was my understanding that with webpack 2 I'm allowed to use es6 imports (almost) independently of the format of the library.
webpack.config.js:
'use strict';
const path = require('path');
const webpack = require('webpack');
function config(env) {
const PRODUCTION = env && typeof env.production !== 'undefined';
const PLUGINS = [
new webpack.DefinePlugin({
DEVELOPMENT: JSON.stringify(!PRODUCTION),
PRODUCTION: JSON.stringify(PRODUCTION)
})
];
if (PRODUCTION) {
PLUGINS.push(new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
dead_code: true,
unused: true,
}
}));
}
return {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.js$/i,
include: /src/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
compact: false,
presets: [['es2015', {modules: false}]]
}
}
]
}
]
},
plugins: PLUGINS,
devtool: 'source-map'
};
}
module.exports = config;
Two questions:
Is this a bug or just not intended to work as I would expect it?
What error does the exception TypeError: __webpack_require__.i(...) is not a function generally indicate?
My mistake: I've used a named import instead of the default import.
Correct:
import $ from 'jquery';
Wrong:
import {$} from 'jquery';