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
Related
I use
python manage.py runserver for django and webpack-dev-server --mode=development for template on local development.
My file structure is like this
/ - /myproj/
/defapp/
/frontend/dist/
/frontend/static/
/frontend/templates/
/frontend/node_modules/
/static/
Now I was ready for deployment on server, so I did webpack --mode=production,
It created the /frontend/dist directory....
then,,,How can I use this ?
Just accessing localhost (manage.py runserver) but no templates appears.
GET https://localhost:8008/static/js/dashboard.0c3e9ffe26656a1dd3c7.bundle.js net::ERR_ABORTED 404 (Not Found)
Maybe I don't understand the basic idea of webpack...
It uses dev server for development but in production, it doesn't require server? am I correct?
My webpack.config.js is below.
const path = require('path');
const { merge } = require('webpack-merge');
const BundleTracker = require('webpack-bundle-tracker');
const entries = {}
for (const fileName of require('fs').readdirSync(path.resolve(__dirname, 'static', 'entries'))) {
entries[fileName.split('.')[0]] = `./static/entries/${fileName}`
}
const baseConfig = {
entry: entries,
output: {
filename: 'js/[name].[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
chunks: 'initial',
name: 'vendor',
},
},
},
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new BundleTracker({
path: __dirname,
filename: 'webpack-stats.json',
}),
]
};
const devConfig = merge(baseConfig, {
mode: 'development',
output: {
publicPath: 'http://localhost:3000/static/',
},
devServer: {
client:{
webSocketURL: 'ws://localhost:3000/ws',
},
port: 3000,
hot: true,
host: '0.0.0.0',
allowedHosts: 'all',
//watchOptions: {
// ignored: /node_modules/
//},
headers: {
"Access-Control-Allow-Origin": "*"
}
},
});
const productConfig = merge(baseConfig, {
mode: 'production',
output: {
publicPath: '/static/'
}
})
module.exports = (env, options) => {
return options.mode === 'production' ? productConfig : devConfig
}
Solution
Add this in django setting.
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'frontend/dist'),
)
then it gathers the file to /static/ folder when python manage.py collectstatic
I have a react component library that I try to make work with applications not running in a node environment, the compiled version is included via a script tag.
Since it does not support imports, I am trying to assign it to the window.
When importing compiled js to the consumer project the following error:
global is not defined pops up and the window does not contain the Components object that I've assigned to the window.
Is there at all possible to make it work for both node and web environments?
Components: (index.ts)
import { Button } from "./src/components/Button/Button";
export { default as Button } from './src/components/Button/Button';
window.Components = {
Button,
};
Webpack:
/* eslint-disable import/no-extraneous-dependencies */
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { merge } = require('webpack-merge')
const { resolve } = require("path");
const TerserPlugin = require('terser-webpack-plugin');
const DtsBundleWebpack = require('dts-bundle-webpack')
const nodeExternals = require('webpack-node-externals');
const commonConfig = require('./webpack.common.config')
module.exports = merge(commonConfig , {
entry: resolve(__dirname, './', 'index.ts'),
mode: 'production',
target: 'node',
node: {global: true},
output: {
filename: '[name].js',
chunkFilename: '[name].js',
libraryTarget: 'umd',
library: 'Components'
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
}),
],
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
},
async: {
test: /[\\/]node_modules[\\/]/,
name: 'async',
chunks: 'async',
minChunks: 4,
},
},
},
},
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
plugins: [
new CleanWebpackPlugin(),
new DtsBundleWebpack({
name: "components",
main: resolve(__dirname, './', 'index.d.ts'),
out: resolve(__dirname, './', 'dist/main.d.ts'),
})
],
});
I'm using babel-plugin-react-css-modules and it seems to be creating the className/styleName, but for some reason it isn't outputting the CSS so that it can be read by the module.
Here's my application: launchpad
I'm using webpack 4.2.0/React 16 and use a babel configuration in the webpack.config imported from a separate config file as you can't set context in .babelrc.
here's the babel config:
{
loader: 'babel-loader',
options: {
'plugins': [
'react-hot-loader/babel',
'transform-runtime',
'transform-object-rest-spread',
'transform-class-properties',
['react-css-modules',
{
context: paths.javascript,
'generateScopedName': '[name]__[local]___[hash:base64:5]',
'filetypes': {
'.scss': {
'syntax': 'postcss-scss',
'plugins': ['postcss-nested']
}
},
'exclude': 'node_modules',
'webpackHotModuleReloading': true
}
]
],
'presets': [
'env',
'react',
'flow'
],
'env': {
'production': {
'presets': ['react-optimize']
}
}
}
}
And here is my webpack:
const webpack = require('webpack')
const path = require('path')
const paths = require('./webpack/config').paths
const outputFiles = require('./webpack/config').outputFiles
const rules = require('./webpack/config').rules
const plugins = require('./webpack/config').plugins
const resolve = require('./webpack/config').resolve
const IS_PRODUCTION = require('./webpack/config').IS_PRODUCTION
const IS_DEVELOPMENT = require('./webpack/config').IS_DEVELOPMENT
const devServer = require('./webpack/dev-server').devServer
const DashboardPlugin = require('webpack-dashboard/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// Default client app entry file
const entry = [
'bootstrap-loader/extractStyles',
path.join(paths.javascript, 'index.js')
]
plugins.push(
// Creates vendor chunk from modules coming from node_modules folder
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: outputFiles.vendor,
minChunks (module) {
const context = module.context
return context && context.indexOf('node_modules') >= 0
}
}),
// Builds index.html from template
new HtmlWebpackPlugin({
template: path.join(paths.source, 'index.html'),
path: paths.build,
filename: 'index.html',
minify: {
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
removeComments: true,
useShortDoctype: true
}
})
)
if (IS_DEVELOPMENT) {
// Development plugins
plugins.push(
// Enables HMR
new webpack.HotModuleReplacementPlugin(),
// Don't emmit build when there was an error while compiling
// No assets are emitted that include errors
new webpack.NoEmitOnErrorsPlugin(),
// Webpack dashboard plugin
new DashboardPlugin()
)
// In development we add 'react-hot-loader' for .js/.jsx files
// Check rules in config.js
rules[0].use.unshift('react-hot-loader/webpack')
entry.unshift('react-hot-loader/patch')
}
// Webpack config
module.exports = {
devtool: IS_PRODUCTION ? false : 'eval-source-map',
context: paths.javascript,
watch: IS_DEVELOPMENT,
entry,
output: {
path: paths.build,
publicPath: '/',
filename: outputFiles.client
},
module: {
rules
},
resolve,
plugins,
devServer
}
If you run npm start or yarn start the code will compile and run, and you can see a basic application layout. If you inspect the react code you will see that the style name is reflected in the component. What doesn't happen is that the style isn't being output. I can't seem to figure out why.
Any help is appreciated.
I have setup my Angular 2 project in .NET Core solution and I have a situation where I need to use .cshtml view files to be rendered from server and use them as templates in Angular components. I am using webpack to AOT bundle them.
How can I exclude templateUrl or template to be excluded (not to be compiled into output .js file) but rather resolved on the fly?
My lazy load component (notfound.component.ts):
import { Component } from "#angular/core";
#Component({
templateUrl: "/Home/PageNotFound" // This is my Controller/Action
})
export class NotFoundComponent
{
}
webpack.config.js:
var webpack = require("webpack");
var clean = require("clean-webpack-plugin");
var compression = require("compression-webpack-plugin");
var path = require("path");
var analyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
"app": "./Client/main-aot.ts" // AoT compilation
},
devtool: "source-map",
output: {
path: __dirname + "/wwwroot/dist/bundle",
//filename: "[name]-[hash:8].bundle.js",
filename: "[name].js",
chunkFilename: "[id]-[hash:8].chunk.js",
publicPath: "/dist/bundle/",
},
resolve: {
extensions: [".ts", ".js"]
},
module: {
rules: [
{
test: /\.ts$/,
use: [
"awesome-typescript-loader",
"angular-router-loader?aot=true&genDir=aot/"
]
}
],
exprContextCritical: false
},
plugins: [
new clean(
[
__dirname + "/wwwroot/dist/bundle"
]
),
new analyzer(),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
},
sourceMap: true
}),
new compression({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
]
};
When I run following NPM command, its giving me error:
"node_modules/.bin/ngc -p tsconfig-aot.json" && webpack --configebpack.config.js
Error: Compilation failed. Resource file not found:
C:/Users/Saad/Documents/Visual Studio 2017/Projects/HelloAngular/HelloAngular/Client/notfound/dist/template/notfound/notfound.html
I'm trying to write tests for my React.js + Redux project using webpack2 to bundle everything and I'd like to use Karma + mocha as my test runners. I have managed to get my webpack.conf.js and karma.conf.js files in order and running simple tests (as well as compiling my bundle), however karma seems to choke whenever a test has a ... operator or the import keyword.
My project structure is fairly simple; config files live in / of the project, react files live in /components/ and tests (named *.test.js) live in /tests/. Whenever I include a test with ... I get the following error:
Error: Module parse failed: /....../components/actions.jsx Unexpected token (5:2)
You may need an appropriate loader to handle this file type.
|
| module.exports = {
| ...generatorActions,
| ...creatorActions
| }
at test/actions/actions.test.js:1088
If I remove the ..., but leave the import statements, I get:
ERROR in ./components/actions.jsx
Module not found: Error: Can't resolve 'creatorActions' in '/..../components'
# ./components/actions.jsx 2:0-43
# ./test/actions/actions.test.js
Firefox 53.0.0 (Mac OS X 10.12.0) ERROR
Error: Cannot find module "generatorActions"
at test/actions/actions.test.js:1090
For reference, the file actions.jsx looks like this:
import generatorActions from 'generatorActions'
import creatorActions from 'creatorActions'
module.exports = {
...generatorActions,
...creatorActions
}
and actions.test.js looks like this:
const expect = require('expect')
const actions = require('../../components/actions.jsx')
describe('Actions', () => {
it('Should exist', () => {
expect(actions).toExist()
})
})
A strange thing that I don't understand is that the lines in the error messages(1088 and 1090) can't correspond to the vanilla files, so I can only assume that they correspond to the generated webpack bundle - so I believe webpack is being invoked. If I completely comment out the contents of actions.jsx the dummy test I have passes (a simple test asserting expect(1).toBe(1)). Here's my webpack.config.js:
function buildConfig(env) {
return require('./build/webpack/webpack.' + (env || 'dev') + '.config.js');
}
module.exports = buildConfig;
And my webpack.dev.config.js looks like:
var path = require('path');
var webpack = require('webpack');
const appRoot = require('app-root-path').path
module.exports = {
context: path.resolve(appRoot, 'components'),
devtool: 'eval',
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
})
],
entry: {
app: './App.jsx',
},
output: {
path: path.resolve(appRoot, 'public/'),
filename: '[name].js'
},
resolve: {
modules: [
path.resolve(appRoot, "components"),
path.resolve(appRoot, "components/common"),
path.resolve(appRoot, "components/common/presentational"),
path.resolve(appRoot, "components/common/components"),
path.resolve(appRoot, "components/creator"),
path.resolve(appRoot, "components/creator/actions"),
path.resolve(appRoot, "components/creator/reducers"),
path.resolve(appRoot, "components/creator/presentational"),
path.resolve(appRoot, "components/creator/components"),
path.resolve(appRoot, "components/generator"),
path.resolve(appRoot, "components/generator/presentational"),
path.resolve(appRoot, "components/generator/stateful"),
path.resolve(appRoot, "components/generator/actions"),
path.resolve(appRoot, "components/generator/reducers"),
path.resolve(appRoot, "node_modules")
],
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
["es2015", {modules: false}],
'react',
'stage-0',
[
"env", {"targets": {"browsers": ["last 2 versions"]}}
]
],
plugins: [
'syntax-dynamic-import',
'transform-async-to-generator',
'transform-regenerator',
'transform-runtime',
'babel-plugin-transform-object-rest-spread'
]
}
}
]
}
}
and my karma.conf
const webpackConfig = require('./webpack.config.js');
module.exports = function(config) {
config.set({
browsers: ['Firefox'],
singleRun: true,
frameworks: ['mocha'],
files: [
'test/**/*.test.js'
],
preprocessors: {
'test/**/*.js': ['webpack'],
'components/**/*.js': ['webpack'],
'components/*.js': ['webpack']
},
reporters: ['mocha'], //, 'coverage', 'mocha'],
client:{
mocha:{
timeout: '5000'
}
},
webpack: webpackConfig,
webpackServer:{
noInfo: true
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
concurrency: Infinity
})
}
I finally figured it out! All I needed to do was change the line const webpackConfig = require('./webpack.config.js'); to const webpackConfig = require('./webpack.config.js')(); in my karma.conf.js