├── .gitignore ├── webpack.config.js ├── src ├── view │ └── Main.js └── app.js ├── package.json ├── index.html ├── LICENSE └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /dist 3 | /ext 4 | node_modules 5 | package-lock.json 6 | 7 | bootstrap.* 8 | classic.json* 9 | modern.json* 10 | .sencha 11 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | module.exports = { 5 | entry: './src/app.js', 6 | mode: 'development', 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: 'bundle.js' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/view/Main.js: -------------------------------------------------------------------------------- 1 | const Panel = Ext.Panel; 2 | const superCls = Panel.prototype; 3 | 4 | export default 5 | Ext.define('App.view.Main', { 6 | extend: Panel, 7 | 8 | title : 'App', 9 | 10 | constructor(...args) { 11 | superCls.constructor.call(this, ...args); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "Ext JS webpack App", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "build": "webpack" 8 | }, 9 | "author": "dongryphon", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "webpack": "^4.42.1", 13 | "webpack-cli": "^3.3.11" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import Main from './view/Main.js'; 2 | 3 | /* 4 | * This call registers your application to be launched when the browser is ready. 5 | */ 6 | Ext.application({ 7 | name: 'App', 8 | 9 | requires: [ 10 | 'Ext.MessageBox' 11 | ], 12 | 13 | launch: function () { 14 | Ext.Viewport.add(new Main()); 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | App 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Don Griffin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Ext JS webpack App 2 | 3 | A simple demonstration of using [webpack](https://webpack.js.org/) to build an 4 | app bundle to go along with the pre-built Ext JS library. 5 | 6 | The goal here is to use fully modern build tools, avoiding Sencha Cmd, so that 7 | we get `import`, `export` and sourcemaps. 8 | 9 | ## Getting Started 10 | 11 | Make an `ext` folder that links to your Ext JS download content. In the 12 | checkout directory, run a command like this: 13 | 14 | $ ln -s ../../sdks/ext-6.5.3 ext 15 | 16 | On Windows: 17 | 18 | > mklink /D ext ..\..\sdks\ext-6.5.3 19 | 20 | Then run `npm run build`: 21 | 22 | $ npm run build 23 | 24 | > app@1.0.0 build ..../extjs-webpack 25 | > webpack 26 | 27 | Hash: 514ce3b213ceda0e6dbe 28 | Version: webpack 4.42.1 29 | Time: 99ms 30 | Built at: 04/05/2020 6:17:04 PM 31 | Asset Size Chunks Chunk Names 32 | bundle.js 4.98 KiB main [emitted] main 33 | Entrypoint main = bundle.js 34 | [./src/app.js] 300 bytes {main} [built] 35 | [./src/view/Main.js] 245 bytes {main} [built] 36 | 37 | That's all. Now load in browser. 38 | 39 | ## Linking It Up 40 | 41 | I've added the theme build to the index file: 42 | 43 | 44 | ... 45 | 47 | 48 | 49 | I added the Ext JS build and theme override just before the webpack `bundle.js`: 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | For a production build, I'd swap the `*-debug.js` files for the optimized/minified 58 | files. 59 | 60 | ## Going Forward 61 | 62 | First thing to note is that all app files are modules and you `import` them. They can 63 | export their constructors like I did in `Main.js`: 64 | 65 | export default 66 | Ext.define('App.view.Main, { 67 | ... 68 | }); 69 | 70 | The `Ext.define()` function needs to be used to extend Ext JS classes and it returns 71 | the class constructor. We export it so that other modules can get it in an ES6 way 72 | as I do in `app.js`: 73 | 74 | import Main from './view/Main.js' 75 | 76 | The class is still placed on the global scope as `App.view.Main`, but following the 77 | ES6 way will clarify relationships for the bundler. 78 | 79 | ### Strict Mode 80 | 81 | Modules use strict mode, so be aware that `callParent` cannot be called from a 82 | function declared in such places. This is easy to work around as I do in `Main`: 83 | 84 | const Panel = Ext.Panel; 85 | const superCls = Panel.prototype; 86 | 87 | export default 88 | Ext.define('App.view.Main', { 89 | extend: Panel, 90 | 91 | title : 'App', 92 | 93 | constructor(...args) { 94 | superCls.constructor.call(this, ...args); 95 | } 96 | }); 97 | 98 | Normally, in Ext JS, the `constructor` override would have used `callParent` to 99 | call the `Panel` super class. 100 | 101 | ## Conclusion 102 | 103 | Using Sencha Themer would be great partner here. Just build your theme and link 104 | it in via the index file. 105 | 106 | I'd love to hear what folks think of this approach! 107 | --------------------------------------------------------------------------------