最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • react+ts+webpack搭建electron项目

    正文概述 掘金(Rise_11)   2021-07-15   661

    项目初始化

    1. 项目目录结构
    ├── 项目根目录
    │ ├── app
    │ │ ├── main      // 主进程模块
    │ │ │    |—— electron.ts
    │ │ │
    │ │ ├── renderer  // 渲染进程模块
    │ │ └── other // 需要之前打包好的一个项目使用webview引入(项目需要)
    │ ├── package.json
    │ └──
    |___
    
    1. 修改package.json
    主要是注意里面的main字段,修改为以下(webpack打包的主线程代码所在位置)
    
    "main": "./dist/electron.js"
    
    
    1. 安装依赖

      • 安装electron

        yarn add electron@11.1.1 -D
        
        安装遇到问题
        
        可在根目录下增加.npmrc,增加以下内容
        
        registry=https://registry.npm.taobao.org/
        electron_mirror="https://npm.taobao.org/mirrors/electron/"
        
        
        
      • 安装react相关

        yarn add react react-router react-router-dom react-dom
        
      • 安装babel(使用babel-loader加ts的插件去编译ts)

        yarn add @babel/polyfill 
        yarn add @babel/core @babel/cli @babel/preset-env @babel/preset-react @babel/preset- typescript @babel/plugin-transform-runtime  @babel/plugin-transform-modules-commonjs -D
        
      • 根目录创建babel.config.js

            module.exports = {
                presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
                plugins: [
                  '@babel/plugin-transform-runtime',
                      [
                    '@babel/plugin-transform-modules-commonjs', 
                    {
                      allowTopLevelThis: true,
                      loose: true,
                      lazy: true
                    }
              ],
              [
                'import', // antd按需加载
                {
                  libraryName: 'antd',
                  libraryDirectory: 'es',
                  style: 'css'
                }
              ]
            ]
          }
        
        
        
      • 安装webpack相关(这里使用的还是4版本,5版本尝试了下,一堆报错改的心累就放弃了)

        yarn add webpack@4.44.1 webpack-cli@3.3.12 webpack-dev-server webpack-merge html-webpack-plugin@4.3.0 clean-webpack-plugin babel-loader -D
        
        
      • 创建webpack配置

        根目录下添加一个webpack文件夹,里面主要有以下文件

        • webpack.base.js
        • webpack.main.dev.js
        • webpack.main.prod.js
        • webpack.render.dev.js
        • webpack.render.prod.js
        // webpack.base.js
        
         const path = require('path')
         const { CleanWebpackPlugin } = require('clean-webpack-plugin')
         const MiniCssExtractPlugin = require('mini-css-extract-plugin')
        
         const isDev = process.env.NODE_ENV !== 'production'
        
         const getCssLoaders = importLoaders => [
           isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
           {
             loader: 'css-loader',
             options: {
               modules: false,
               sourceMap: isDev,
               importLoaders
             }
           }
         ]
        
         module.exports = {
           resolve: {
             extensions: ['.js', '.jsx', '.ts', '.tsx'],
             alias: {
               '@src': path.join(__dirname, '../', 'app/renderer'),
               '@viz': path.join(__dirname, '../', 'app/viz/index1.html')
             }
           },
           module: {
             rules: [
               {
                 oneOf: [
                   {
                     test: /\.(js|jsx|ts|tsx)$/,
                     exclude: /node_modules/,
                     use: {
                       loader: 'babel-loader',
                       options: { cacheDirectory: true }
                     }
                   },
                   {
                     test: /\.css$/,
                     use: getCssLoaders(0)
                   },
                   {
                     test: /\.less$/,
                     use: [
                       ...getCssLoaders(1),
                       {
                         loader: 'less-loader',
                         options: {
                           sourceMap: isDev
                         }
                       }
                     ]
                   },
                   {
                     test: /\.(jpg|png|jpeg|gif)$/,
                     use: [
                       {
                         loader: 'file-loader',
                         options: {
                           name: '[name]_[hash].[ext]',
                           outputPath: 'images/'
                         }
                       }
                     ]
                   }
                 ]
               }
             ]
           },
           plugins: [new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['**/*', '!electron.js'] })]
         }
        
        
        
        // webpack.main.dev.js
             const path = require('path')
             const baseConfig = require('./webpack.base.js')
             const webpackMerge = require('webpack-merge')
        
             const mainConfig = {
               entry: path.resolve(__dirname, '../app/main/electron.ts'),
               target: 'electron-main',
               output: {
                 filename: 'electron.js',
                 path: path.resolve(__dirname, '../dist')
               },
               devtool: 'inline-source-map',
               mode: 'development'
             }
        
             module.exports = webpackMerge.merge(baseConfig, mainConfig)
        
        
        
        // webpack.main.prod.js
        
                const path = require('path')
                const baseConfig = require('./webpack.base.js')
                const webpackMerge = require('webpack-merge')
                const webpack = require('webpack')
        
                const prodConfig = {
                  entry: path.resolve(__dirname, '../app/main/electron.ts'),
                  target: 'electron-main',
                  output: {
                    filename: 'electron.js',
                    path: path.resolve(__dirname, '../dist')
                  },
                  devtool: 'inline-source-map',
                  mode: 'production',
                  plugins: [
                    new webpack.DefinePlugin({
                      __dirname: '__dirname'
                    })
                  ]
                }
        
                module.exports = webpackMerge.merge(baseConfig, prodConfig)
        
        
        
        // webpack.render.dev.js
        
        const path = require('path')
        const webpackMerge = require('webpack-merge')
        const baseConfig = require('./webpack.base.js')
        const HtmlWebpackPlugin = require('html-webpack-plugin')
        
        const devConfig = {
         mode: 'development',
         entry: {
           index: path.resolve(__dirname, '../app/renderer/app.tsx')
         },
         output: {
           filename: '[name].[hash].js',
           path: path.resolve(__dirname, '../dist')
         },
         target: 'electron-renderer',
         devtool: 'inline-source-map',
         devServer: {
           contentBase: path.join(__dirname, '../dist'),
           compress: true,
           host: '127.0.0.1',
           port: 7001,
           hot: true
         },
         plugins: [
           new HtmlWebpackPlugin({
             template: path.resolve(__dirname, '../app/renderer/index.html'),
             filename: path.resolve(__dirname, '../dist/index.html'),
             chunks: ['index']
           })
         ]
        }
        
        module.exports = webpackMerge.merge(baseConfig, devConfig)
        
        
        
        // webpack.render.prod.js
        
          const path = require('path')
          const webpackMerge = require('webpack-merge')
          const baseConfig = require('./webpack.base.js')
          const HtmlWebpackPlugin = require('html-webpack-plugin')
        
          const prodConfig = {
            mode: 'production',
            entry: {
              index: path.resolve(__dirname, '../app/renderer/app.tsx')
            },
            output: {
              filename: '[name].[hash].js',
              path: path.resolve(__dirname, '../dist')
            },
            target: 'electron-renderer',
            devtool: 'inline-source-map',
            plugins: [
              new HtmlWebpackPlugin({
                template: path.resolve(__dirname, '../app/renderer/index.html'),
                filename: path.resolve(__dirname, '../dist/index.html'),
                chunks: ['index']
              })
            ]
          }
        
          module.exports = webpackMerge.merge(baseConfig, prodConfig)
        
        
        
      • 编写一些代码

        • 在main文件夹下的electron.ts加入如下代码

          import path from 'path'
          import { app, BrowserWindow } from 'electron'
          import isDev from 'electron-is-dev'
          
          let mainWindow = null
          
          
          function createWindow() {
            mainWindow = new BrowserWindow({
              width: 1200,
              height: 800,
              webPreferences: {
                nodeIntegration: true,
                enableRemoteModule: true,
                contextIsolation: false,
                webviewTag: true
              }
            })
          
            if (isDev) {
              mainWindow.loadURL(`http://127.0.0.1:7001`)
              mainWindow.webContents.openDevTools()
            } else {
              mainWindow.loadURL(`file://${path.join(__dirname, '../dist/index.html')}`)
            }
          
            mainWindow.on('close', () => {
              mainWindow = null
            })
          }
          
          
          app.whenReady().then(() => {
            createWindow()
            app.on('activate', () => {
              if (BrowserWindow.getAllWindows().length === 0) createWindow()
            })
          })
          
          
          
        • 在renderer文件夹下添加index.html

             <!DOCTYPE html>
             <html lang="en">
               <head>
                 <meta charset="UTF-8" />
                 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                 <title>Document</title>
               </head>
               <body>
                 <div id="root"></div>
               </body>
             </html>
          
          
        • 在renderer文件夹下添加app.tsx

          import React from 'react';
          import ReactDOM from 'react-dom';
          import { HashRouter as Router, Route, Switch } from 'react-router-dom';
          
          function App() {
              return (
                <Router>
                  <Switch>
                    <Route path="/">
                      <div>基础模板</div>
                      
                    </Route>
                  </Switch>
                </Router>
              );
            }
          
            ReactDOM.render(<App />, document.getElementById('root'));
          
          
          
      • 配置package.json文件的脚本

        
            scripts": {
             "start": "concurrently \"yarn start:render\" \"wait-on http://127.0.0.1:7001 && yarn start:main \"", // 开发环境一个指令整体启动项目,需要安装concurrently和wait-on
             "start:main": "webpack --config ./webpack/webpack.main.dev.js && electron ./dist/electron.js", // 启动主进程
             "start:render": "webpack-dev-server --config ./webpack/webpack.render.dev.js", // 启动渲染进程
             "build": "yarn build:main && yarn build:render", // 打包同上
             "build:main": "webpack --config ./webpack/webpack.main.prod.js",
             "build:render": "webpack --config ./webpack/webpack.render.prod.js",
             "ele:pack": "electron-builder"  // 打包后使用electron-builder(需要安装)构建exe文件
             }
        
        
      • 一些其他的额外配置

        • elsint
        • husky
        • css采用css in js
        • 路由使用react-router-config来管理
      • 更多配置见git仓库

      • 主要参考掘金小册 Electron + React 从 0 到 1 实现简历平台实战


    下载网 » react+ts+webpack搭建electron项目

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元