How to use Typescript in Laravel Project with Vue as frontend? - laravel

I want to use typescript in Vue in Laravel project.
I already checked all tutorials for that but none of them works for me give below
teej.
Titas Gailius.
sebastiandedeyne.
when ever i run 'npm run dev' i get this error
ERROR in ./resources/js/app.ts
Module build failed: Error: You may be using an old version of webpack; please check you're using at least version 4
at successfulTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:144:15)
at Object.getTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:34:12)
at Object.loader (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\index.js:17:41)
# multi ./resources/js/app.ts ./resources/sass/app.scss

Im facing this problem from quite some days but i was finally be able to find the solution for that so im Sharing my exp to folks who want to use typescript instead of javascript in vue in laravel. so here is the instruction
here the intruction
Laravel 5.7 uses Laravel-mix which down the line uses webpack 3 . Which is not what we want for typescript to work in laravel project.
Initialize your project
Let's create a new Project. You can also do this on Existing project just make sure to convert js code to ts.
First make sure you have composer and laravel installed
sh
laravel new Laravel-Vue-Typecript
Open the project in your any favraite code editor.
Open the package.json and add these packages to devdependencies
{
"devDependencies": {
"auto-loader": "^0.2.0",
"autoprefixer": "^9.4.1",
"axios": "^0.18",
"bootstrap": "^4.0.0",
"lodash": "^4.17.5",
"popper.js": "^1.12",
"jquery": "^3.2",
"cross-env": "^5.1",
"css-loader": "^1.0.1",
"mini-css-extract-plugin": "^0.4.5",
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"ts-loader": "^5.3.1",
"typescript": "^3.2.1",
"uglifyjs-webpack-plugin": "^2.0.1",
"vue": "^2.5.17",
"vue-class-component": "^6.3.2",
"vue-property-decorator": "^7.2.0",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2",
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17"
}
}
Now install these npm packages with
npm install
Add Typescript Support
Then rename these files
Laravel-Vue-Typecript/
├─ resources/js/app.js => resources/js/app.ts
└─ resources/js/bootstrap.js => resources/js/bootstrap.ts
Now Change the Code in app.ts, bootstrap.ts and
resources/js/components/ExampleComponent.vue
// app.ts
import "./bootstrap"
import Vue from "vue"
import ExampleComponent from "./components/ExampleComponent.vue"
Vue.component('example', ExampleComponent)
new Vue({
el: '#app'
})
// bootstrap.ts
import axios from 'axios';
import * as _ from 'lodash';
import jQuery from 'jquery';
import * as Popper from 'popper.js';
import 'bootstrap';
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token : HTMLMetaElement | null = document.head!.querySelector('meta[name="csrf-token"]');
if (token) {
axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
// resources/js/components/ExampleComponent.vue
<template>
<h1>This is an example component</h1>
</template>
<script lang="ts">
import Vue from 'vue'
import Component from "vue-class-component"
#Component
export default class ExampleComponent extends Vue {
mounted() : void {
console.log("hello");
}
}
</script>
```
Create typings.d.ts file inside resources/js and add these lines.
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
declare module 'jquery';
declare module 'lodash';
Now Create tsconfig.json, webpack.config.js and postcss.config.js in the root of your project and these lines of code to them respectivly
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true
},
"include": [
"resources/js/**/*"
],
"exclude": [
"node_modules",
"vendor"
]
}
webpack.config.json
const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');
let env = process.env.NODE_ENV
let isDev = env === 'development'
const WEBPACK_CONFIG = {
mode: env,
entry: {
app: ['./resources/js/app.ts', './resources/sass/app.scss'],
},
output: {
publicPath: './public',
path: path.resolve(__dirname, 'public'),
filename: 'js/[name].js',
chunkFilename: 'js/chunks/app.js'
},
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader',
options: { appendTsSuffixTo: [/\.vue$/] },
exclude: /node_modules/,
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
],
exclude: /node_modules/,
}
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
new VueLoaderPlugin(),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer()
]
}
})
],
resolve: {
extensions: ['.js', '.jsx', '.vue', '.ts', '.tsx'],
alias: {
vue$: 'vue/dist/vue.esm.js',
},
},
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
}
if (!isDev) {
WEBPACK_CONFIG.optimization = {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin({})
]
}
WEBPACK_CONFIG.plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: 'production'
}
})
)
}
module.exports = WEBPACK_CONFIG
postcss.config.js
module.exports = {
plugins: {
'autoprefixer': {}
} }
Now finally change the "scripts" in package.json
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=webpack.config.js"
},
Finally build the project
and run the npm scripts by
npm run dev // To build the Project
npm run watch // To build and watch for files changes and build automagically
npm run prod // for production

Related

Getting error : Support for the experimental syntax 'jsx' isn't currently enabled . When trying to add animation in react-native-web project

In my project, I'm using the reanimate library to add animations, but I'm receiving an error
https://stackoverflow.com/questions/63005011/support-for-the-experimental-syntax-jsx-isnt-currently-enabled
I follow all the steps mention in the link but none of them work for me
My package.json file
{
"name": "animation",
"version": "0.1.0",
"private": true,
"dependencies": {
"#react-spring/native": "^9.6.1",
"#react-spring/web": "^9.6.1",
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"babel-polyfill": "^6.26.0",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-reanimated": "^2.14.4",
"react-native-web": "^0.18.10",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/preset-env": "^7.20.2",
"#babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.2",
"url-loader": "^4.1.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
webpack.config.js
// web/webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const appDirectory = path.resolve(__dirname, "../");
// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
test: /\.js$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [
path.resolve(appDirectory, "index.web.js"),
path.resolve(appDirectory, "src"),
path.resolve(appDirectory, "node_modules/react-native-uncompiled"),
],
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
// The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
presets: [
"#babel/preset-react",
"module:metro-react-native-babel-preset",
],
// Re-write paths to import only the modules needed by the app
plugins: [
"#babel/plugin-syntax-jsx",
"react-native-web",
"react-native-reanimated/plugin",
],
},
},
};
// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: "url-loader",
options: {
name: "[name].[ext]",
esModule: false,
},
},
};
module.exports = {
entry: [
// load any web API polyfills
path.resolve(appDirectory, "polyfills-web.js"),
// your web-specific entry file
path.resolve(appDirectory, "index.web.js"),
],
// configures where the build ends up
output: {
filename: "bundle.web.js",
path: path.resolve(appDirectory, "dist"),
},
// ...the rest of your config
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "./index.html",
}),
new webpack.EnvironmentPlugin({ JEST_WORKER_ID: null }),
new webpack.DefinePlugin({ process: { env: {} } }),
],
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
resolve: {
// This will only alias the exact import "react-native"
alias: {
"react-native$": "react-native-web",
},
// If you're working on a multi-platform React Native app, web-specific
// module implementations should be written in files using the extension
// `.web.js`.
extensions: [".web.js", ".js"],
},
};

Why does my App JS file increase after each run of NPM run dev?

For some strange reason, whenever I run npm run dev, each time, my /public/js/app.js file seems to gain a few MB, regardless of not changing any code.
webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.vue()
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
])
.webpackConfig(require('./webpack.config'));
if (mix.inProduction()) {
mix.version();
}
if (!mix.inProduction()) {
mix.bundleAnalyzer({
analyzerMode: 'static'
});
}
webpack.config.js
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
},
},
};
app.js
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
const appName = window.document.getElementsByTagName('title')[0]?.innerText
|| 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });
The problem seems to be the .vue() in the webpack file, which, when run without, reduces the app.js size down to 700kb. But, of course, without it, I get:
ERROR in ./resources/js/Pages/Dashboard.vue 1:0 Module parse failed:
Unexpected token (1:0) 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
package.json
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"#inertiajs/inertia": "^0.10.0",
"#inertiajs/inertia-vue3": "^0.5.1",
"#inertiajs/progress": "^0.2.6",
"#tailwindcss/forms": "^0.2.1",
"#vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.4",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"laravel-mix-bundle-analyzer": "^1.0.5",
"lodash": "^4.17.19",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"tailwindcss": "^2.2.7",
"vue": "^3.0.5",
"vue-loader": "^16.1.2"
},
"dependencies": {
"#headlessui/vue": "^1.4.0",
"#heroicons/vue": "^1.0.4"
}
}
Please can someone point me in the right direction?

Webpack, Mix and Vuetify loader : SassError: Expected newline

I use Vuetify loader in my Laravel project but compilation doesn't work.
Laravel : 8.46
Vue : 2.6.14
Vuetify : 2.5.3
This is my package.json
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"axios": "^0.21",
"deepmerge": "^4.2.2",
"laravel-mix": "^6.0.6",
"path": "^0.12.7",
"postcss": "^8.1.14",
"sass": "^1.34.1",
"sass-loader": "^12.1.0",
"vue": "^2.6.14",
"vue-loader": "^15.9.5",
"vue-template-compiler": "^2.6.14",
"vuetify": "^2.5.3",
"vuetify-loader": "^1.7.2"
}
}
My webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
mix.webpackConfig({
resolve: {
alias: {
'#': path.resolve(__dirname, 'resources/js/')
}
},
module: {
rules: [
{
test: /\.s(c|a)ss$/,
use: [
"sass-loader",
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
indentedSyntax: true
},
},
},
],
},
],
},
plugins: [
new VuetifyLoaderPlugin()
],
});
mix.js('resources/js/app.js', 'public/js')
.vue()
//.extract(['vue'])
.postCss('resources/css/app.css', 'public/css', [
//
]);
if (mix.inProduction()) {
mix.version();
}
My entry :
require('./bootstrap');
import Vue from 'vue'
import vuetify from '#/plugins/vuetify'
new Vue({
vuetify,
}).$mount('#app')
And my vuetify plugin :
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
But when I run yarn dev, I have an error :
...
ERROR in ./node_modules/vuetify/src/styles/main.sass (./node_modules/css-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[2]!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[3]!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-22[0].rules[0].use[3]!./node_modules/vuetify/src/styles/main.sass)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Expected newline.
╷
4 │ var content = require("!!../../../css-loader/dist/cjs.js!../../../sass-loader/dist/cjs.js??clonedRuleSet-22[0].rules[0].use[3]!./main.sass");
│ ^
╵
node_modules/vuetify/src/styles/main.sass 4:141 root stylesheet
webpack compiled with 95 errors
I follow Vuetify documentation and Mix documentation.

Tiptap for Vuetify SassError: SassError: Invalid CSS

Anyone have this error appear when trying to install the WYSIWYG editor Tiptap for Vuefity?
This is the error:
ERROR in ./node_modules/vuetify/src/styles/main.sass (./node_modules/css-loader/dist/cjs.js??ref--4-1!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js??ref--4-3!./node_modules/vuetify/src/styles/main.sass)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Invalid CSS after " #content": expected "}", was "($material-light); "
on line 3 of node_modules/vuetify/src/styles/tools/_theme.sass
from line 6 of node_modules/vuetify/src/styles/tools/_index.sass
from line 3 of /home/fc-gui/node_modules/vuetify/src/styles/main.sass
>> #content($material-light); }
----^
And then this is my main Vue file:
/* eslint no-console: 0 */
import '#mdi/font/css/materialdesignicons.css'
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from '../app.vue'
import Vuetify from 'vuetify'
import getShop from '../api/shops'
import customizationApi from '../api/customization'
import { routes } from '../router/routes'
import store from '../store/store'
import axios from 'axios'
import VueFriendlyIframe from 'vue-friendly-iframe';
import { TiptapVuetifyPlugin } from 'tiptap-vuetify'
Vue.use(VueFriendlyIframe)
Vue.use(Vuetify)
Vue.use(VueRouter)
Vue.use(TiptapVuetifyPlugin)
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) => {
if(to.name == null){
getShop.get(
data => {
if(data.setup) {
next({ name: 'emailCustomize'});
}
else {
next({ name: 'plans'})
}
});
}
else {
next();
}
});
document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
vuetify: new Vuetify(),
router,
store,
render: h => h(App)
}).$mount()
document.body.appendChild(app.$el)
})
And finally my package.json file
{
"name": "fresh-credit",
"private": true,
"dependencies": {
"#rails/actioncable": "^6.0.0-alpha",
"#rails/activestorage": "^6.0.0-alpha",
"#rails/ujs": "^6.0.0-alpha",
"#rails/webpacker": "^4.0.7",
"animate.css": "^3.7.2",
"axios": "^0.19.0",
"babel-preset-stage-2": "^6.24.1",
"chart.js": "^2.8.0",
"lodash": "^4.17.15",
"postcss-loader": "^3.0.0",
"stylus": "^0.54.7",
"stylus-loader": "^3.0.2",
"tiptap-extensions": "^1.28.6",
"tiptap-vuetify": "^2.13.2",
"turbolinks": "^5.2.0",
"vue": "^2.6.10",
"vue-breadcrumbs": "^1.2.0",
"vue-chartist": "^2.2.1",
"vue-chartjs": "^3.4.2",
"vue-click-outside": "^1.0.7",
"vue-friendly-iframe": "^0.17.0",
"vue-loader": "^15.7.1",
"vue-router": "^3.1.3",
"vue-template-compiler": "^2.6.10",
"vuetify": "^2.0.18",
"vuex": "^3.1.2"
},
"version": "0.1.0",
"devDependencies": {
"#mdi/font": "^4.4.95",
"deepmerge": "^4.2.2",
"fibers": "^4.0.2",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"webpack-dev-server": "^3.8.0",
"webpack-merge": "^4.1.0"
}
}
Nothing seems to be working. I even took a look at those files mentioned in the error and it doesn't look like that's the source of the issue. But for completeness here is the file _theme.sass
#mixin theme ($component)
.theme--light.#{$component}
#content($material-light)
.theme--dark.#{$component}
#content($material-dark)
Throw this in your Webpack.config.js rules and specify the options based on the sass-loader version you are using
{
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader#^7.0.0
options: {
implementation: require('sass'),
fiber: require('fibers'),
indentedSyntax: true // optional
},
// Requires sass-loader#^8.0.0
options: {
implementation: require('sass'),
sassOptions: {
fiber: require('fibers'),
indentedSyntax: true // optional
},
},
},
],
},
And ensure that you are using sass instead of node-sass in your package.json. from my experience I found that if you have had node-sass previously installed, you might want to delete node modules and re-run npm install
You might also want to install vue-style-loader and css-loader as i don't see them in your package.json
More information can be found in these links
https://github.com/vuetifyjs/vuetify/issues/7950
https://vuetifyjs.com/en/introduction/frequently-asked-questions/
https://github.com/vuetifyjs/vuetify/issues/7323

How to insert image files in Electron + React.js + Webpack desktop app package for Mac OS

I am building a desktop application for Mac OS with Electron + React + Webpack mode.
When I build a Electron desktop app as production version, I would like to insert some image files in the setup file(Test.app and Test.dmg) and use the image as following:
let Logo = process.resourcesPath + '/logo.png';
class Loading extends Component {
render() {
return (
<div className={styles.container}>
<img className={styles.logo} src={Logo} />
...
</div>
);
}
}
But this app can't get the image because the logo.png file didn't be include in Test.app/Content/Resources/ directory when I run 'npm run package' command and build a Test.app for Mac OS.
Here, the issue is as following:
GET file:///Applications/Test.app/Contents/Resources/logo.png
net::ERR_FILE_NOT_FOUND
I would like to insert this image file in my Test.app package for Mac OS.
Please help me how to insert some image files into Test.app package for a Mac OS desktop application.
webpack.config.base.js
import path from 'path';
import webpack from 'webpack';
import { dependencies as externals } from './app/package.json';
export default {
externals: Object.keys(externals || {}),
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
}]
},
output: {
path: path.join(__dirname, 'app'),
filename: 'bundle.js',
// https://github.com/webpack/webpack/issues/1114
libraryTarget: 'commonjs2'
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
modules: [
path.join(__dirname, 'app'),
'node_modules',
],
},
plugins: [
new webpack.NamedModulesPlugin(),
],
};
webpack.config.production.js
import path from 'path';
import webpack from 'webpack';
import validate from 'webpack-validator';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import merge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';
export default validate(merge(baseConfig, {
devtool: 'cheap-module-source-map',
entry: './app/index',
output: {
publicPath: '../dist/'
},
module: {
loaders: [
// Extract all .global.css to style.css as is
{
test: /\.global\.css$/,
loader: ExtractTextPlugin.extract(
'style-loader',
'css-loader'
)
},
// Pipe other styles through css modules and append to style.css
{
test: /^((?!\.global).)*\.css$/,
loader: ExtractTextPlugin.extract(
'style-loader',
'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'
)
},
// Fonts
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?name=fonts/[hash].[ext]&limit=50000&mimetype=application/font-woff' },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?name=fonts/[hash].[ext]&limit=50000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name=fonts/[hash].[ext]' },
// Images
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
loader: 'url-loader'
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new BabiliPlugin({
// Disable deadcode until https://github.com/babel/babili/issues/385 fixed
deadcode: false,
}),
new webpack.optimize.UglifyJsPlugin({
compressor: {
screw_ie8: true,
warnings: false
}
}),
new ExtractTextPlugin('style.css', { allChunks: true }),
new HtmlWebpackPlugin({
filename: 'app.html',
template: 'app/app.html',
inject: false
})
],
target: 'electron-renderer'
}));
webpack.config.electron.js
/**
* Build config for electron 'Main Process' file
*/
import webpack from 'webpack';
import validate from 'webpack-validator';
import merge from 'webpack-merge';
import BabiliPlugin from 'babili-webpack-plugin';
import baseConfig from './webpack.config.base';
export default validate(merge(baseConfig, {
devtool: 'source-map',
entry: ['babel-polyfill', './main.development'],
// 'main.js' in root
output: {
path: __dirname,
filename: './main.js'
},
plugins: [
deadcode: false,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
})
],
target: 'electron-main',
node: {
__dirname: false,
__filename: false
}
}));
scripts section of package.json
"scripts": {
"test": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 node --trace-warnings ./test/runTests.js",
"test-all": "npm run lint && npm run flow && npm run test && npm run build && npm run test-e2e",
"test-watch": "npm test -- --watch",
"test-e2e": "cross-env NODE_ENV=test BABEL_DISABLE_CACHE=1 node --trace-warnings ./test/runTests.js e2e",
"lint": "eslint --cache --format=node_modules/eslint-formatter-pretty .",
"lint-fix": "npm run lint -- --fix",
"lint-styles": "stylelint app/*.css app/components/*.css --syntax scss",
"hot-updates-server": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js",
"build": "concurrently \"npm run copy-images\" \"npm run build-main\" \"npm run build-renderer\"",
"build-dll": "cross-env NODE_ENV=development node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.dev.dll.js --progress --profile --colors",
"build-main": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.main.prod.js --progress --profile --colors",
"build-renderer": "cross-env NODE_ENV=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.prod.js --progress --profile --colors",
"start": "cross-env NODE_ENV=production electron ./app/",
"prestart": "npm run build",
"flow": "flow",
"flow-typed": "rm -rf flow-typed && flow-typed install --overwrite || true",
"start-hot-renderer": "cross-env HOT=1 NODE_ENV=development electron -r babel-register -r babel-polyfill ./app/main.development",
"postinstall": "concurrently \"npm run flow-typed\" \"npm run build-dll\" \"install-app-deps\" \"node node_modules/fbjs-scripts/node/check-dev-engines.js package.json\"",
"dev": "cross-env START_HOT=1 npm run hot-updates-server",
"package": "npm run build && build --publish never",
"package-win": "npm run build && build --win --x64",
"package-linux": "npm run build && build --linux",
"package-all": "npm run build && build -mwl",
"cleanup": "mop -v",
"copy-images": "cp -Rf app/shared/images/ app/dist/images/"
},
"browserslist": "electron 1.4",
"build": {
"productName": "Test",
"appId": "org.Test",
"files": [
"dist/",
"node_modules/",
"app.html",
"main.js",
"main.js.map",
"package.json"
],
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
},
"win": {
"target": [
"nsis"
]
},
"linux": {
"target": [
"deb",
"AppImage"
]
},
"directories": {
"buildResources": "resources",
"output": "release"
}
},
after electron app installed, it put all the source code and resource files into a .asar package. so to insert any image, u have to use a directory outside of app.
Generally this directory can be a Document folder.
const { remote } = require('electron');
let tempFolder =path.join( remote.app.getPath("documents"), 'AppFiles');
use the tempFolder directory to save image.

Resources