├── .babelrc
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .nvmrc
├── .prettierignore
├── .yo-rc.json
├── LICENSE
├── README.md
├── config.json
├── dist
├── index.html
└── vue-pell-editor.js
├── jest.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── prettier.config.js
├── src
├── js
│ ├── app.vue
│ ├── components
│ │ └── VuePellEditor.vue
│ ├── main.ts
│ ├── shims-tsx.d.ts
│ ├── shims-vue.d.ts
│ └── vue-pell-editor.ts
└── structure
│ ├── index.html
│ └── readme.txt
├── tests
└── unit
│ └── example.spec.js
├── tsconfig.json
├── tslint.json
├── webpack
├── stats.json
├── utils.js
├── webpack.config.base.babel.js
├── webpack.dev.babel.js
└── webpack.prod.babel.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env", {
5 | "useBuiltIns": "entry",
6 | "debug": false
7 | }]
8 | ],
9 | "plugins": [
10 | "@babel/plugin-syntax-dynamic-import",
11 | "@babel/plugin-proposal-class-properties",
12 | "@babel/plugin-proposal-object-rest-spread"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 0.25%
2 | IE 11
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [*.php]
16 | indent_size = 4
17 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parserOptions: {
6 | parser: 'typescript-eslint-parser',
7 | ecmaVersion: 2017,
8 | sourceType: 'module'
9 | },
10 | env: {
11 | browser: true,
12 | node: true,
13 | es6: true,
14 | jquery: true,
15 | jest: true
16 | },
17 | extends: [
18 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
19 | 'standard',
20 | 'plugin:vue/recommended',
21 | 'plugin:prettier/recommended'
22 | ],
23 | plugins: ['typescript'],
24 | // check if imports actually resolve
25 | settings: {
26 | 'import/resolver': {
27 | webpack: {
28 | config: 'webpack/webpack.prod.babel.js'
29 | }
30 | }
31 | },
32 | rules: {
33 | indent: 0,
34 | 'no-console': 0,
35 | 'object-curly-spacing': 0,
36 | 'space-before-function-paren': 0
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Node ###
2 |
3 | # Logs
4 | logs
5 | npm-debug.log*
6 | yarn-debug.log*
7 | yarn-error.log*
8 |
9 | # Optional npm cache directory
10 | .npm
11 | .config
12 | .node*
13 |
14 | # Dependency directories
15 | /node_modules
16 | /jspm_packages
17 | /bower_components
18 |
19 | # Yarn Integrity file
20 | .yarn-integrity
21 |
22 | # Optional eslint cache
23 | .eslintcache
24 |
25 | # dotenv environment variables file(s)
26 | .env
27 | .env.*
28 |
29 | # Build generated
30 |
31 | dist/index.html
32 | dist/app.css
33 | dist/app.js
34 | build/
35 | doc/
36 |
37 | # Map-Files
38 | *.js.map
39 |
40 | ### Sass-Files ###
41 | *.sassc
42 | .sass-cache
43 | *.css.map
44 |
45 | ### SublimeText ###
46 | # cache files for sublime text
47 | *.tmlanguage.cache
48 | *.tmPreferences.cache
49 | *.stTheme.cache
50 |
51 | ### Test Results ###
52 | tests/e2e/screenshots
53 | tests/e2e/videos
54 |
55 | # workspace files are user-specific
56 | *.sublime-workspace
57 |
58 | # project files should be checked into the repository, unless a significant
59 | # proportion of contributors will probably not be using SublimeText
60 | # *.sublime-project
61 |
62 |
63 | ### VisualStudioCode ###
64 | .vscode/*
65 | .v8flags.*
66 | !.vscode/settings.json
67 | !.vscode/tasks.json
68 | !.vscode/launch.json
69 | !.vscode/extensions.json
70 |
71 | ### WebStorm/IntelliJ ###
72 | /.idea
73 | modules.xml
74 | *.ipr
75 |
76 |
77 | ### System Files ###
78 | .DS_Store
79 |
80 | # Windows thumbnail cache files
81 | Thumbs.db
82 | ehthumbs.db
83 | ehthumbs_vista.db
84 |
85 | # Folder config file
86 | Desktop.ini
87 |
88 | # Recycle Bin used on file shares
89 | $RECYCLE.BIN/
90 |
91 | # Thumbnails
92 | ._*
93 |
94 | # Files that might appear in the root of a volume
95 | .DocumentRevisions-V100
96 | .fseventsd
97 | .Spotlight-V100
98 | .TemporaryItems
99 | .Trashes
100 | .VolumeIcon.icns
101 | .com.apple.timemachine.donotpresent
102 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | tests
2 | webpack
3 | dist/*.html
4 | dist/app.js
5 | src/structure
6 | src/js/app.vue
7 | src/js/main.ts
8 | src/js/shims-*
9 | .*
10 | *.config.js
11 | config.json
12 | tsconfig.json
13 | tslint.json
14 | *.lock
15 | package-lock.json
16 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 9
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | **/*.scss
2 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-kittn": {
3 | "promptValues": {
4 | "projectusage": "webpackApp",
5 | "projectcssstructure": "sassAtomic",
6 | "projectbreakpointunit": "em",
7 | "projectthemecolor": "#29b8f2",
8 | "projectstylelint": false,
9 | "projectprettier": true,
10 | "projecttypescript": true,
11 | "projecttestingunit": true,
12 | "projecttestinge2e": false,
13 | "projecttestingwallaby": false,
14 | "projectversion": "0.0.1",
15 | "projectmail": "larseichler.le@gmail.com",
16 | "projecturl": "https://github.com/CinKon/vue-pell-editor.git"
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Lars Eichler
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 | # vue-pell-editor
2 |
3 | > Vue wrapper for [pell WYSIWYG text editor](https://github.com/jaredreich/pell)
4 |
5 | ## Installation
6 |
7 | **Install via NPM or Yarn:**
8 |
9 | ```shell
10 | $ npm install --save vue-pell-editor
11 | # OR
12 | $ yarn add vue-pell-editor
13 | ```
14 |
15 | ## Usage
16 |
17 | main.js:
18 |
19 | ```javascript
20 | import Vue from 'vue'
21 | import VuePellEditor from 'vue-pell-editor'
22 |
23 | Vue.use(VuePellEditor)
24 | ```
25 |
26 | example.vue:
27 |
28 | ```vue
29 |
30 |
")}},quote:{icon:"“ ”",title:"Quote",result:function(){return u("formatBlock","
")}},olist:{icon:"#",title:"Ordered List",result:function(){return u("insertOrderedList")}},ulist:{icon:"•",title:"Unordered List",result:function(){return u("insertUnorderedList")}},code:{icon:"</>",title:"Code",result:function(){return u("formatBlock","")}},line:{icon:"―",title:"Horizontal Line",result:function(){return u("insertHorizontalRule")}},link:{icon:"🔗",title:"Link",result:function(){var t=window.prompt("Enter the link URL");t&&u("createLink",t)}},image:{icon:"📷",title:"Image",result:function(){var t=window.prompt("Enter the image URL");t&&u("insertImage",t)}}},l={actionbar:"pell-actionbar",button:"pell-button",content:"pell-content",selected:"pell-button-selected"},s=function(t){var i=t.actions?t.actions.map(function(t){return"string"==typeof t?a[t]:a[t.name]?e({},a[t.name],t):t}):Object.keys(a).map(function(t){return a[t]}),s=e({},l,t.classes),c=t.defaultParagraphSeparator||"div",f=o("div");f.className=s.actionbar,r(t.element,f);var d=t.element.content=o("div");return d.contentEditable=!0,d.className=s.content,d.oninput=function(e){var n=e.target.firstChild;n&&3===n.nodeType?u("formatBlock","<"+c+">"):"
"===d.innerHTML&&(d.innerHTML=""),t.onChange(d.innerHTML)},d.onkeydown=function(t){"Tab"===t.key?t.preventDefault():"Enter"===t.key&&"blockquote"===function(t){return document.queryCommandValue(t)}("formatBlock")&&setTimeout(function(){return u("formatBlock","<"+c+">")},0)},r(t.element,d),i.forEach(function(t){var e=o("button");if(e.className=s.button,e.innerHTML=t.icon,e.title=t.title,e.setAttribute("type","button"),e.onclick=function(){return t.result()&&d.focus()},t.state){var i=function(){return e.classList[t.state()?"add":"remove"](s.selected)};n(d,"keyup",i),n(d,"mouseup",i),n(e,"click",i)}r(f,e)}),t.styleWithCSS&&u("styleWithCSS"),u("defaultParagraphSeparator",c),t.element},c={exec:u,init:s};t.exec=u,t.init=s,t.default=c,Object.defineProperty(t,"__esModule",{value:!0})}(e)},86:function(t,e,n){"use strict";var r=n(25);n.n(r).a},87:function(t,e,n){(t.exports=n(88)(!1)).push([t.i,"\n.pell{border:1px solid rgba(10,10,10,.1)\n}\n.pell,.pell-content{box-sizing:border-box\n}\n.pell-content{height:300px;outline:0;overflow-y:auto;padding:10px\n}\n.pell-actionbar{background-color:#fff;border-bottom:1px solid rgba(10,10,10,.1)\n}\n.pell-button{background-color:transparent;border:none;cursor:pointer;height:30px;outline:0;vertical-align:bottom;width:30px\n}\n.pell-button-selected{background-color:#f0f0f0\n}\n.vp-editor{position:relative\n}\n.vp-editor__placeholder{color:#ddd;font-style:italic;left:10px;position:absolute;top:42px\n}",""])},88:function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"==typeof btoa){var o=function(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}(r),i=r.sources.map(function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"});return[n].concat(i).concat([o]).join("\n")}return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{var u=[];for(o=0;o =7.6.0" 127 | }, 128 | "title": "SiteTitle" 129 | } 130 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ file, options, env }) => ({ 2 | parser: 'postcss-scss', 3 | plugins: { 4 | 'postcss-normalize': options && options.normalize !== false ? {} : false, 5 | 'postcss-custom-selectors': {}, 6 | 'postcss-custom-media': {}, 7 | 'postcss-pseudo-class-any-link': {}, 8 | 'postcss-custom-properties': { 9 | warnings: false 10 | }, 11 | 'postcss-calc': {}, 12 | 'postcss-aspect-ratio': {}, 13 | 'postcss-easings': {}, 14 | 'postcss-assets': { 15 | basePath: './', 16 | loadPaths: options.dist ? [options.dist.cssimg] : [] 17 | }, 18 | 'autoprefixer': { 19 | cascade: false, 20 | grid: true 21 | }, 22 | 'postcss-svg': {}, 23 | 'postcss-short-size': {}, 24 | 'postcss-flexbugs-fixes': {}, 25 | 'cssnano': env !== 'production' ? false : { 26 | discardComments: { removeAll: true }, 27 | zindex: false, 28 | discardUnused: false, 29 | reduceIdents: false, 30 | mergeIdents: false 31 | } 32 | } 33 | }) 34 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | tabWidth: 2, 4 | semi: false, 5 | singleQuote: true, 6 | trailingComma: 'none', 7 | bracketSpacing: true, 8 | arrowParens: 'always', 9 | proseWrap: 'never' 10 | } 11 | -------------------------------------------------------------------------------- /src/js/app.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 66 | -------------------------------------------------------------------------------- /src/js/components/VuePellEditor.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 |14 | 15 | 16 | 150 | 151 | 166 | -------------------------------------------------------------------------------- /src/js/main.ts: -------------------------------------------------------------------------------- 1 | // Main JS File 2 | import '@babel/polyfill' 3 | import Vue from 'vue' 4 | import App from './app' 5 | import VuePellEditor from './vue-pell-editor' 6 | Vue.use(VuePellEditor) 7 | 8 | // Vue App 9 | /* eslint-disable no-new */ 10 | new Vue({ 11 | el: '#app', 12 | render: (h) => h(App) 13 | }) 14 | -------------------------------------------------------------------------------- /src/js/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/js/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /src/js/vue-pell-editor.ts: -------------------------------------------------------------------------------- 1 | import VuePellEditor from './components/VuePellEditor.vue' 2 | 3 | VuePellEditor.install = (Vue: any, options?: Object) => { 4 | Vue.component('VuePellEditor', VuePellEditor) 5 | } 6 | 7 | const install = (Vue: any) => { 8 | VuePellEditor.install(Vue) 9 | } 10 | 11 | export default install 12 | -------------------------------------------------------------------------------- /src/structure/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |11 | {{ placeholder }} 12 |13 |7 | vue-pell-editor 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |Hello World
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/structure/readme.txt: -------------------------------------------------------------------------------- 1 | Place your uncompiled Template Files here. 2 | -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | // Import the `mount()` method from the test utils 2 | // and the component you want to test 3 | import { shallow, mount } from '@vue/test-utils' 4 | import App from '../../src/js/app.vue' 5 | 6 | describe('Testing Sidebar', () => { 7 | // Now mount the component and you have the wrapper 8 | const wrapper = mount(App) 9 | 10 | it('App is available', () => { 11 | expect(wrapper.html()) 12 | }) 13 | 14 | it('Data is there', () => { 15 | expect(wrapper.vm.message).toBe('Hello World i am Vue') 16 | }) 17 | 18 | it('render the right markup', () => { 19 | expect(wrapper.html()).toBe('Hello World i am Vue
') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "target": "es5", 5 | "module": "esnext", 6 | "strict": true, 7 | "jsx": "preserve", 8 | "importHelpers": true, 9 | "moduleResolution": "node", 10 | "allowSyntheticDefaultImports": true, 11 | "sourceMap": true, 12 | "baseUrl": ".", 13 | "types": ["node", "jest"], 14 | "paths": { 15 | "@/*": ["src/js/*"], 16 | "components/*": ["src/js/components/*"], 17 | "shared/*": ["src/js/shared/*"], 18 | "lang/*": ["src/js/lang/*"] 19 | }, 20 | "lib": ["es7", "dom", "dom.iterable", "scripthost"] 21 | }, 22 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint-config-standard", 6 | "tslint-config-prettier", 7 | "@kurosame/tslint-config-vue" 8 | ], 9 | "linterOptions": { 10 | "exclude": ["node_modules/**"] 11 | }, 12 | "rules": { 13 | "quotemark": [true, "single"], 14 | "indent": [true, "spaces", 2], 15 | "class-name": false, 16 | "interface-name": false, 17 | "ordered-imports": false, 18 | "object-literal-sort-keys": false, 19 | "no-consecutive-blank-lines": false, 20 | "space-before-function-paren": false, 21 | "no-console": false, 22 | "no-submodule-imports": false, 23 | "no-implicit-dependencies": false, 24 | "max-line-length": [true, 100] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webpack/utils.js: -------------------------------------------------------------------------------- 1 | import { getIfUtils, removeEmpty } from 'webpack-config-utils' 2 | import path from 'path' 3 | import kittnConf from '../config.json' 4 | 5 | exports.getIfUtils = getIfUtils 6 | exports.removeEmpty = removeEmpty 7 | 8 | exports.kittnConf = kittnConf 9 | exports.entryPoints = kittnConf.src.jsEntryPoints 10 | 11 | /* 12 | |-------------------------------------------------------------------------- 13 | | Setting some paths for our Application 14 | |-------------------------------------------------------------------------- 15 | */ 16 | const paths = {} 17 | paths.ROOT_PATH = path.resolve(__dirname, '..') 18 | paths.PUBLIC_PATH = path.join(paths.ROOT_PATH, kittnConf.dist.webpackpublic) 19 | paths.ASSETS_PATH = kittnConf.dist.webpackassets 20 | paths.SRC_ROOT = path.resolve(paths.ROOT_PATH, kittnConf.src.base) 21 | paths.CSS_ROOT = path.resolve(paths.ROOT_PATH, kittnConf.src.style) 22 | paths.LOADER_PATH = path.join(paths.ROOT_PATH, kittnConf.src.js) 23 | exports.paths = paths 24 | 25 | /* 26 | |-------------------------------------------------------------------------- 27 | | Helper Functions 28 | |-------------------------------------------------------------------------- 29 | */ 30 | exports.resolve = function (dir) { 31 | return path.join(__dirname, '..', dir) 32 | } 33 | 34 | exports.assetsPath = function (_path) { 35 | return path.posix.join(paths.ASSETS_PATH, _path); 36 | } 37 | -------------------------------------------------------------------------------- /webpack/webpack.config.base.babel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Webpack Config for Javascript Bundling 3 | * 4 | * @package generator-kittn 5 | * @author Lars Eichler6 | */ 7 | import path from 'path' 8 | import webpack from 'webpack' 9 | import WebpackBar from 'webpackbar' 10 | import Stylish from 'webpack-stylish' 11 | import HtmlWebpackPlugin from 'html-webpack-plugin' 12 | import ExtractTextPlugin from 'extract-text-webpack-plugin' 13 | import OptimizeCSSPlugin from 'optimize-css-assets-webpack-plugin' 14 | import { VueLoaderPlugin } from 'vue-loader' 15 | 16 | const utils = require('./utils') 17 | const nodeEnv = process.env.NODE_ENV || 'production' 18 | 19 | const { ifProduction, ifDevelopment } = utils.getIfUtils(nodeEnv) 20 | 21 | const CSS_LOADERS = [ 22 | { 23 | loader: 'css-loader', 24 | options: { 25 | autoprefixer: false, 26 | sourceMap: ifProduction(false, true), 27 | url: true 28 | } 29 | }, 30 | { 31 | loader: 'postcss-loader', 32 | options: { 33 | sourceMap: ifProduction(false, true), 34 | config: { 35 | ctx: { 36 | normalize: true 37 | } 38 | } 39 | } 40 | }, 41 | { 42 | loader: 'sass-loader', 43 | options: { 44 | includePaths: [utils.resolve(utils.kittnConf.src.style)], 45 | sourceMap: ifProduction(false, true) 46 | } 47 | } 48 | ] 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | Let the config begin 53 | |-------------------------------------------------------------------------- 54 | */ 55 | export default { 56 | entry: utils.removeEmpty(utils.entryPoints), 57 | output: { 58 | pathinfo: ifDevelopment(true, false), 59 | path: utils.paths.PUBLIC_PATH 60 | }, 61 | stats: 'none', 62 | resolve: { 63 | extensions: ['.vue', '.js', '.ts', '.tsx'], 64 | modules: [utils.resolve(utils.kittnConf.src.base), utils.resolve('node_modules')], 65 | alias: { 66 | components: path.resolve(utils.paths.LOADER_PATH, 'components/'), 67 | src: utils.resolve(utils.kittnConf.src.base) 68 | } 69 | }, 70 | module: { 71 | rules: [ 72 | { 73 | enforce: 'pre', 74 | test: /\.(js|vue)$/, 75 | loader: 'eslint-loader', 76 | options: { 77 | configFile: './.eslintrc.js', 78 | formatter: require('eslint-friendly-formatter') 79 | }, 80 | exclude: /node_modules/, 81 | include: utils.resolve(utils.kittnConf.src.base) 82 | }, 83 | { 84 | test: /\.js$/, 85 | include: utils.resolve(utils.kittnConf.src.base), 86 | exclude: /node_modules/, 87 | use: { 88 | loader: 'babel-loader', 89 | options: { 90 | cacheDirectory: true 91 | } 92 | } 93 | }, 94 | { 95 | test: /\.vue$/, 96 | loader: 'vue-loader' 97 | }, 98 | { 99 | test: /\.css$/, 100 | use: ['vue-style-loader', 'css-loader'] 101 | }, 102 | { 103 | test: /\.scss$/, 104 | include: [utils.resolve(utils.kittnConf.src.style), utils.resolve(utils.kittnConf.src.js)], 105 | exclude: [utils.resolve('node_modules'), utils.resolve(utils.kittnConf.dist.base)], 106 | use: ['vue-style-loader', ...CSS_LOADERS] 107 | }, 108 | { 109 | test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/, 110 | exclude: [ 111 | path.resolve(utils.paths.SRC_ROOT, 'images/vectors/'), 112 | path.resolve(utils.paths.SRC_ROOT, 'images/vectorsSingle/') 113 | ], 114 | use: [ 115 | { 116 | loader: 'url-loader', 117 | options: { 118 | limit: 8192, 119 | fallback: 'file-loader', 120 | outputPath: utils.assetsPath('img/'), 121 | publicPath: utils.assetsPath('img/'), 122 | name: '[name].[ext]' 123 | } 124 | } 125 | ] 126 | }, 127 | { 128 | test: /\.(eot|ttf|woff|woff2)(\?\S*)?$/, 129 | use: [ 130 | { 131 | loader: 'file-loader', 132 | query: { 133 | outputPath: utils.assetsPath('fonts/'), 134 | publicPath: 'fonts/', 135 | name: '[name].[ext]' 136 | } 137 | } 138 | ] 139 | }, 140 | { 141 | test: /\.svg$/, 142 | include: [ 143 | path.resolve(utils.paths.SRC_ROOT, 'images/vectors/'), 144 | path.resolve(utils.paths.SRC_ROOT, 'images/vectorsSingle/') 145 | ], 146 | use: [ 147 | { 148 | loader: 'svg-sprite-loader' 149 | }, 150 | 'svg-transform-loader', 151 | 'svgo-loader' 152 | ] 153 | }, 154 | { 155 | test: /\.tsx?$/, 156 | exclude: /node_modules/, 157 | use: [ 158 | 'babel-loader', 159 | { 160 | loader: 'ts-loader', 161 | options: { 162 | transpileOnly: true, 163 | experimentalWatchApi: true 164 | } 165 | } 166 | ] 167 | } 168 | ] 169 | }, 170 | plugins: utils.removeEmpty([ 171 | new VueLoaderPlugin(), 172 | new WebpackBar(), 173 | new Stylish(), 174 | new webpack.DefinePlugin({ 175 | 'process.env': { 176 | NODE_ENV: JSON.stringify(nodeEnv) 177 | } 178 | }), 179 | // new ExtractTextPlugin({ 180 | // filename: utils.assetsPath('[name].css'), 181 | // allChunks: true 182 | // }), 183 | // new OptimizeCSSPlugin({ 184 | // cssProcessorOptions: { 185 | // safe: true 186 | // } 187 | // }), 188 | new HtmlWebpackPlugin({ 189 | filename: 'index.html', 190 | template: utils.kittnConf.src.structure + 'index.html', 191 | inject: false, 192 | hash: true, 193 | minify: { 194 | removeComments: true, 195 | collapseWhitespace: true, 196 | removeAttributeQuotes: false 197 | }, 198 | chunksSortMode: 'dependency' 199 | }) 200 | ]) 201 | } 202 | -------------------------------------------------------------------------------- /webpack/webpack.dev.babel.js: -------------------------------------------------------------------------------- 1 | import webpack from 'webpack' 2 | import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin' 3 | // import WriteFilePlugin from 'write-file-webpack-plugin' 4 | import utils from './utils' 5 | 6 | const baseWebpackConfig = require('./webpack.config.base.babel.js') 7 | const merge = require('webpack-merge') 8 | const path = require('path') 9 | const portfinder = require('portfinder') 10 | 11 | /* 12 | |-------------------------------------------------------------------------- 13 | | Defining Entry Points, could be used to manually split Parts of the Application, for example 14 | | Admin Javascript and FrontEnd JavaScript 15 | |-------------------------------------------------------------------------- 16 | */ 17 | let entries = utils.entryPoints 18 | 19 | const HOST = 'localhost' 20 | const PORT = utils.kittnConf.browsersync.port 21 | 22 | const devWebpackConfig = merge(baseWebpackConfig.default, { 23 | devtool: 'eval-source-map', 24 | entry: utils.removeEmpty(entries), 25 | output: { 26 | publicPath: '/', 27 | filename: utils.assetsPath('js/[name].js'), 28 | chunkFilename: utils.assetsPath('js/chunks/[name].js') 29 | }, 30 | 31 | devServer: { 32 | clientLogLevel: 'warning', 33 | historyApiFallback: { 34 | rewrites: [{ from: /.*/, to: path.posix.join(utils.kittnConf.dist.markup, 'index.html') }] 35 | }, 36 | hot: true, 37 | compress: true, 38 | host: HOST, 39 | port: PORT, 40 | proxy: [ 41 | { 42 | path: /\/(?!__webpack_hmr).+/ 43 | } 44 | ], 45 | quiet: true, 46 | stats: { colors: true }, 47 | contentBase: path.join(__dirname, `../${utils.kittnConf.src.base}`), 48 | publicPath: '/', 49 | open: utils.kittnConf.browsersync.openbrowser, 50 | overlay: true 51 | }, 52 | 53 | plugins: [ 54 | new webpack.HotModuleReplacementPlugin(), 55 | new webpack.NoEmitOnErrorsPlugin() 56 | 57 | // only needed if you want to write the files to your harddrive in dev-mode 58 | // new WriteFilePlugin({ 59 | // log: false, 60 | // test: /^(?!.+(?:hot-update.(js|json))).+$/ 61 | // }) 62 | ] 63 | }) 64 | 65 | module.exports = new Promise((resolve, reject) => { 66 | portfinder.basePort = process.env.PORT || utils.kittnConf.browsersync.port 67 | portfinder.getPort((err, port) => { 68 | if (err) { 69 | reject(err) 70 | } else { 71 | // publish the new Port, necessary for e2e tests 72 | process.env.PORT = port 73 | // add port to devServer config 74 | devWebpackConfig.devServer.port = port 75 | 76 | // Add FriendlyErrorsPlugin 77 | devWebpackConfig.plugins.push( 78 | new FriendlyErrorsWebpackPlugin({ 79 | compilationSuccessInfo: { 80 | messages: [ 81 | `Your application is running here: http://${devWebpackConfig.devServer.host}:${port}` 82 | ] 83 | } 84 | }) 85 | ) 86 | 87 | resolve(devWebpackConfig) 88 | } 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /webpack/webpack.prod.babel.js: -------------------------------------------------------------------------------- 1 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' 2 | import CleanWebpackPlugin from 'clean-webpack-plugin' 3 | import path from 'path' 4 | const merge = require('webpack-merge') 5 | const utils = require('./utils') 6 | const baseWebpackConfig = require('./webpack.config.base.babel.js') 7 | 8 | /* 9 | |-------------------------------------------------------------------------- 10 | | Merge the configs 11 | |-------------------------------------------------------------------------- 12 | */ 13 | const prodWebpackConfig = merge(baseWebpackConfig.default, { 14 | devtool: '', 15 | output: { 16 | filename: utils.assetsPath('[name].js'), 17 | chunkFilename: utils.assetsPath('chunks/[name].js'), 18 | publicPath: './', 19 | library: 'VuePellEditor', 20 | libraryExport: 'default', 21 | libraryTarget: 'umd' 22 | }, 23 | plugins: [ 24 | new CleanWebpackPlugin([utils.resolve(utils.kittnConf.dist.base)], { 25 | root: path.resolve(utils.paths.PUBLIC_PATH, '..'), 26 | beforeEmit: true 27 | }), 28 | 29 | new BundleAnalyzerPlugin({ 30 | analyzerMode: 'disabled', 31 | generateStatsFile: true, 32 | statsFilename: `${utils.paths.ROOT_PATH}/webpack/stats.json`, 33 | logLevel: 'info' 34 | }) 35 | ] 36 | }) 37 | 38 | module.exports = prodWebpackConfig 39 | --------------------------------------------------------------------------------