mirror of
https://github.com/nextcloud/spreed.git
synced 2025-12-18 05:20:50 +01:00
Create Message component
Signed-off-by: Marco Ambrosini <marcoambrosini@pm.me>
This commit is contained in:
parent
88d7d7820e
commit
5e9c3400c7
18 changed files with 42690 additions and 71 deletions
99
.eslintrc.js
Normal file
99
.eslintrc.js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
jest: true
|
||||
},
|
||||
globals: {
|
||||
t: true,
|
||||
n: true,
|
||||
OC: true,
|
||||
OCA: true,
|
||||
Vue: true,
|
||||
VueRouter: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
ecmaVersion: 6
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/warnings',
|
||||
'plugin:node/recommended',
|
||||
'plugin:vue/essential',
|
||||
'plugin:vue/recommended',
|
||||
'plugin:nextcloud/recommended',
|
||||
'standard'
|
||||
],
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
webpack: {
|
||||
config: 'webpack.common.js'
|
||||
},
|
||||
node: {
|
||||
paths: ['src'],
|
||||
extensions: ['.js', '.vue']
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: ['vue', 'node'],
|
||||
rules: {
|
||||
// space before function ()
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
// curly braces always space
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
// stay consistent with array brackets
|
||||
'array-bracket-newline': ['error', 'consistent'],
|
||||
// 1tbs brace style
|
||||
'brace-style': 'error',
|
||||
// tabs only
|
||||
indent: ['error', 'tab'],
|
||||
'no-tabs': ['off'],
|
||||
'vue/html-indent': ['error', 'tab'],
|
||||
// only debug console
|
||||
'no-console': ['error', { allow: ['error', 'warn', 'info', 'debug'] }],
|
||||
// classes blocks
|
||||
'padded-blocks': ['error', { classes: 'always' }],
|
||||
// always have the operator in front
|
||||
'operator-linebreak': ['error', 'before'],
|
||||
// ternary on multiline
|
||||
'multiline-ternary': ['error', 'always-multiline'],
|
||||
// force proper JSDocs
|
||||
'valid-jsdoc': [2, {
|
||||
'prefer': {
|
||||
'return': 'returns'
|
||||
},
|
||||
'requireReturn': false,
|
||||
'requireReturnDescription': false
|
||||
}],
|
||||
// es6 import/export and require
|
||||
'node/no-unpublished-require': ['off'],
|
||||
'node/no-unsupported-features/es-syntax': ['off'],
|
||||
// PascalCase components names for vuejs
|
||||
// https://vuejs.org/v2/style-guide/#Single-file-component-filename-casing-strongly-recommended
|
||||
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
|
||||
// force name
|
||||
'vue/match-component-file-name': ['error', {
|
||||
'extensions': ['jsx', 'vue', 'js'],
|
||||
'shouldMatchCase': true
|
||||
}],
|
||||
// space before self-closing elements
|
||||
'vue/html-closing-bracket-spacing': 'error',
|
||||
// no ending html tag on a new line
|
||||
'vue/html-closing-bracket-newline': ['error', { multiline: 'never' }],
|
||||
// code spacing with attributes
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
singleline: 3,
|
||||
multiline: {
|
||||
max: 3,
|
||||
allowFirstLine: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
root: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
|
||||
env:
|
||||
browser: true
|
||||
amd: true
|
||||
|
||||
globals:
|
||||
$: false
|
||||
escapeHTML: false
|
||||
OC: false
|
||||
OCA: false
|
||||
t: false
|
||||
Backbone: false
|
||||
_: false
|
||||
Clipboard: false
|
||||
oc_defaults: false
|
||||
Hashes: false
|
||||
|
||||
rules:
|
||||
curly: error
|
||||
eqeqeq: ["error", "smart"]
|
||||
guard-for-in: error
|
||||
no-console: off
|
||||
no-fallthrough: error
|
||||
no-mixed-spaces-and-tabs: error
|
||||
no-unused-vars: error
|
||||
no-use-before-define: error
|
||||
semi: ["error", "always"]
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -11,3 +11,5 @@ tests/php/coverage-html
|
|||
tests/php/clover.xml
|
||||
tests/integration/vendor
|
||||
tests/integration/output
|
||||
|
||||
js
|
||||
|
|
|
|||
10041
js/Talk.js
Normal file
10041
js/Talk.js
Normal file
File diff suppressed because one or more lines are too long
1
js/Talk.js.map
Normal file
1
js/Talk.js.map
Normal file
File diff suppressed because one or more lines are too long
10801
js/talk.js
Normal file
10801
js/talk.js
Normal file
File diff suppressed because one or more lines are too long
1
js/talk.js.map
Normal file
1
js/talk.js.map
Normal file
File diff suppressed because one or more lines are too long
10041
js/vueexample.js
Normal file
10041
js/vueexample.js
Normal file
File diff suppressed because one or more lines are too long
1
js/vueexample.js.map
Normal file
1
js/vueexample.js.map
Normal file
File diff suppressed because one or more lines are too long
11247
package-lock.json
generated
Normal file
11247
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
77
package.json
Normal file
77
package.json
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "talk",
|
||||
"description": "A simple Nextcloud app using vue-components",
|
||||
"version": "3.2.0",
|
||||
"author": "John Molakvoæ <skjnldsv@protonmail.com>",
|
||||
"contributors": [
|
||||
"John Molakvoæ <skjnldsv@protonmail.com>"
|
||||
],
|
||||
"keywords": [
|
||||
"nextcloud",
|
||||
"vueexample",
|
||||
"app",
|
||||
"dev",
|
||||
"vuejs"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/skjnldsv/vueexample/issues"
|
||||
},
|
||||
"repository": {
|
||||
"url": "https://github.com/skjnldsv/vueexample",
|
||||
"type": "git"
|
||||
},
|
||||
"homepage": "https://github.com/skjnldsv/vueexample",
|
||||
"license": "agpl",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack --config webpack.dev.js",
|
||||
"watch": "webpack --progress --watch --config webpack.dev.js",
|
||||
"build": "webpack --progress --hide-modules --config webpack.prod.js",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"lint:fix": "eslint --ext .js,.vue src --fix",
|
||||
"stylelint": "stylelint src",
|
||||
"stylelint:fix": "stylelint src --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"nextcloud-vue": "^0.12.3",
|
||||
"vue": "^2.6.10"
|
||||
},
|
||||
"browserslist": [
|
||||
"extends browserslist-config-nextcloud"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "^7.6.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.29",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"browserslist-config-nextcloud": "0.0.1",
|
||||
"css-loader": "^3.2.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-standard": "^12.0.0",
|
||||
"eslint-import-resolver-webpack": "^0.11.1",
|
||||
"eslint-loader": "^3.0.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-nextcloud": "^0.3.0",
|
||||
"eslint-plugin-node": "^9.2.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"eslint-plugin-vue": "^5.2.3",
|
||||
"node-sass": "^4.12.0",
|
||||
"sass-loader": "^7.3.1",
|
||||
"stylelint": "^8.4.0",
|
||||
"stylelint-config-recommended-scss": "^3.3.0",
|
||||
"stylelint-scss": "^3.10.1",
|
||||
"stylelint-webpack-plugin": "^0.10.5",
|
||||
"vue-loader": "^15.7.1",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack": "^4.40.1",
|
||||
"webpack-cli": "^3.3.8",
|
||||
"webpack-merge": "^4.2.2",
|
||||
"webpack-node-externals": "^1.7.2"
|
||||
}
|
||||
}
|
||||
178
src/App.vue
Normal file
178
src/App.vue
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<Content :class="{'icon-loading': loading}" app-name="vueexample">
|
||||
<AppNavigation>
|
||||
<AppNavigationNew v-if="!loading" :text="t('vueexample', 'New XXXXXX')" :disabled="false"
|
||||
button-id="new-vueexample-button" button-class="icon-add" @click="newButtonAction" />
|
||||
<ul id="app-vueexample-navigation">
|
||||
<AppNavigationItem v-for="item in menu" :key="item.key" :item="item" />
|
||||
</ul>
|
||||
<AppNavigationSettings>
|
||||
Example settings
|
||||
</AppNavigationSettings>
|
||||
</AppNavigation>
|
||||
<AppContent>
|
||||
<span>This is the content</span>
|
||||
<button @click="show = !show">
|
||||
Toggle sidebar
|
||||
</button>
|
||||
<Message
|
||||
user-name="Barthelemy dsflkjds"
|
||||
:is-first-message="true"
|
||||
message-time="16:12"
|
||||
message-text="This is a test message" />
|
||||
</AppContent>
|
||||
<AppSidebar v-show="show" title="christmas-image-2018-12-25-00:01:12.jpg" subtitle="4,3 MB, last edited 41 days ago"
|
||||
:actions="menu" :starred.sync="starred"
|
||||
@close="show=false">
|
||||
<template #action>
|
||||
<button class="primary">
|
||||
Button 1
|
||||
</button>
|
||||
<input id="link-checkbox" name="link-checkbox" class="checkbox link-checkbox"
|
||||
type="checkbox">
|
||||
<label for="link-checkbox" class="link-checkbox-label">Do something</label>
|
||||
</template>
|
||||
<AppSidebarTab name="Chat" icon="icon-talk">
|
||||
this is the chat tab
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Activity" icon="icon-activity">
|
||||
this is the activity tab
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Comments" icon="icon-comment">
|
||||
this is the comments tab
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Sharing" icon="icon-shared">
|
||||
this is the sharing tab
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Versions" icon="icon-history">
|
||||
this is the versions tab
|
||||
</AppSidebarTab>
|
||||
</AppSidebar>
|
||||
</Content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Content from 'nextcloud-vue/dist/Components/Content'
|
||||
import AppContent from 'nextcloud-vue/dist/Components/AppContent'
|
||||
import AppNavigation from 'nextcloud-vue/dist/Components/AppNavigation'
|
||||
import AppNavigationItem from 'nextcloud-vue/dist/Components/AppNavigationItem'
|
||||
import AppNavigationNew from 'nextcloud-vue/dist/Components/AppNavigationNew'
|
||||
import AppNavigationSettings from 'nextcloud-vue/dist/Components/AppNavigationSettings'
|
||||
import AppSidebar from 'nextcloud-vue/dist/Components/AppSidebar'
|
||||
import AppSidebarTab from 'nextcloud-vue/dist/Components/AppSidebarTab'
|
||||
import Message from './components/Message'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
Content,
|
||||
AppContent,
|
||||
AppNavigation,
|
||||
AppNavigationItem,
|
||||
AppNavigationNew,
|
||||
AppNavigationSettings,
|
||||
AppSidebar,
|
||||
AppSidebarTab,
|
||||
Message
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
loading: false,
|
||||
date: Date.now() + 86400000 * 3,
|
||||
date2: Date.now() + 86400000 * 3 + Math.floor(Math.random() * 86400000 / 2),
|
||||
show: true,
|
||||
starred: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// App navigation
|
||||
menu: function() {
|
||||
return [
|
||||
{
|
||||
id: 'app-category-your-apps',
|
||||
classes: [],
|
||||
href: '#1',
|
||||
// action: this.log,
|
||||
icon: 'icon-category-installed',
|
||||
text: t('settings', 'Your apps')
|
||||
},
|
||||
{
|
||||
caption: true,
|
||||
text: t('vueexample', 'Section')
|
||||
},
|
||||
{
|
||||
id: 'app-category-enabled',
|
||||
classes: [],
|
||||
icon: 'icon-category-enabled',
|
||||
href: '#2',
|
||||
utils: {
|
||||
actions: [{
|
||||
icon: 'icon-delete',
|
||||
text: t('settings', 'Remove group'),
|
||||
action: function() {
|
||||
alert('remove')
|
||||
}
|
||||
}]
|
||||
},
|
||||
text: t('settings', 'Active apps')
|
||||
},
|
||||
{
|
||||
id: 'app-category-enabled',
|
||||
classes: [],
|
||||
icon: 'icon-category-enabled',
|
||||
href: '#3',
|
||||
utils: {
|
||||
counter: 123,
|
||||
actions: [
|
||||
{
|
||||
icon: 'icon-delete',
|
||||
text: t('settings', 'Remove group'),
|
||||
action: function() {
|
||||
alert('remove')
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: 'icon-delete',
|
||||
text: t('settings', 'Remove group'),
|
||||
action: function() {
|
||||
alert('remove')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
text: t('settings', 'Active apps')
|
||||
},
|
||||
{
|
||||
id: 'app-category-disabled',
|
||||
classes: [],
|
||||
icon: 'icon-category-disabled',
|
||||
href: '#4',
|
||||
undo: true,
|
||||
text: t('settings', 'Disabled apps')
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addOption(val) {
|
||||
this.options.push(val)
|
||||
this.select.push(val)
|
||||
},
|
||||
previous(data) {
|
||||
console.debug(data)
|
||||
},
|
||||
next(data) {
|
||||
console.debug(data)
|
||||
},
|
||||
close(data) {
|
||||
console.debug(data)
|
||||
},
|
||||
newButtonAction(e) {
|
||||
console.debug(e)
|
||||
},
|
||||
log(e) {
|
||||
console.debug(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
102
src/components/Message.vue
Normal file
102
src/components/Message.vue
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Marco Ambrosini <marcoambrosini@pm.me>
|
||||
-
|
||||
- @author Marco Ambrosini <marcoambrosini@pm.me>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="message">
|
||||
<div class="message-avatar">
|
||||
<Avatar v-if="isFirstMessage" :user="userName" :display-name="userName" />
|
||||
</div>
|
||||
<div class="message-main">
|
||||
<div v-if="isFirstMessage" class="message-main-header">
|
||||
<h6>{{ userName }}</h6>
|
||||
</div>
|
||||
<div class="message-main-text">
|
||||
<p>{{messageText}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-right">
|
||||
<h6>{{ messageTime }}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from 'nextcloud-vue/dist/Components/Avatar'
|
||||
|
||||
export default {
|
||||
name: 'Message',
|
||||
components: {
|
||||
Avatar
|
||||
},
|
||||
props: {
|
||||
userName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
messageTime: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
messageText: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isFirstMessage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.message {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 12px 0 12px 0;
|
||||
margin: auto;
|
||||
&-avatar {
|
||||
width: 52px;
|
||||
min-width: 52px;
|
||||
padding: 4px 8px 0 8px;
|
||||
}
|
||||
&-main {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
font-size: 20;
|
||||
&-header {
|
||||
color: #989898;
|
||||
}
|
||||
&-text {
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
&-right {
|
||||
min-width: 90px;
|
||||
color: #989898;
|
||||
padding: 0px 8px 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
33
src/main.js
Normal file
33
src/main.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
|
||||
Vue.prototype.t = t
|
||||
Vue.prototype.n = n
|
||||
Vue.prototype.OC = OC
|
||||
Vue.prototype.OCA = OCA
|
||||
|
||||
export default new Vue({
|
||||
el: '#content',
|
||||
render: h => h(App)
|
||||
})
|
||||
|
|
@ -2,45 +2,7 @@
|
|||
/** @var \OCP\IL10N $l */
|
||||
/** @var array $_ */
|
||||
|
||||
style('spreed', 'merged');
|
||||
script('spreed', 'merged');
|
||||
script('spreed', 'talk');
|
||||
|
||||
\OC::$server->getEventDispatcher()->dispatch('\OCP\Collaboration\Resources::loadAdditionalScripts');
|
||||
?>
|
||||
|
||||
<div id="app" class="nc-enable-screensharing-extension" data-token="<?php p($_['token']) ?>">
|
||||
<script type="text/json" id="signaling-settings">
|
||||
<?php echo json_encode($_['signaling-settings']) ?>
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="app-navigation" class="icon-loading">
|
||||
<form id="oca-spreedme-add-room">
|
||||
<input id="select-participants" class="select2-offscreen" type="text" placeholder="<?php p($l->t('New conversation …')) ?>"/>
|
||||
</form>
|
||||
<ul id="spreedme-room-list" class="with-icon">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="app-content" class="participants-1">
|
||||
|
||||
<div id="app-content-wrapper">
|
||||
<button id="video-fullscreen" class="icon-fullscreen force-icon-white-in-call icon-shadow hidden" data-placement="bottom" data-toggle="tooltip" data-original-title="<?php p($l->t('Fullscreen (f)')) ?>"></button>
|
||||
|
||||
<div id="videos"></div>
|
||||
|
||||
<div id="screens"></div>
|
||||
|
||||
<div id="emptycontent">
|
||||
<div id="emptycontent-icon" class="icon-talk"></div>
|
||||
<h2><?php p($l->t('Join a conversation or start a new one')) ?></h2>
|
||||
<p class="emptycontent-additional"><?php p($l->t('Say hi to your friends and colleagues!')) ?></p>
|
||||
<div id="shareRoomContainer" class="" style="display: inline-flex">
|
||||
<input id="shareRoomInput" class="share-room-input hidden" readonly="readonly" type="text"/>
|
||||
<div id="shareRoomClipboardButton" class="shareRoomClipboard icon-clippy hidden" data-clipboard-target="#shareRoomInput"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
?>
|
||||
50
webpack.common.js
Normal file
50
webpack.common.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
const path = require('path')
|
||||
const { VueLoaderPlugin } = require('vue-loader')
|
||||
const StyleLintPlugin = require('stylelint-webpack-plugin')
|
||||
const packageJson = require('./package.json')
|
||||
const appName = packageJson.name
|
||||
|
||||
module.exports = {
|
||||
entry: path.join(__dirname, 'src', 'main.js'),
|
||||
output: {
|
||||
path: path.resolve(__dirname, './js'),
|
||||
publicPath: '/js/',
|
||||
filename: `${appName}.js`,
|
||||
chunkFilename: 'chunks/[name]-[hash].js'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: ['vue-style-loader', 'css-loader', 'sass-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(js|vue)$/,
|
||||
use: 'eslint-loader',
|
||||
exclude: /node_modules/,
|
||||
enforce: 'pre'
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new StyleLintPlugin()
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['*', '.js', '.vue']
|
||||
}
|
||||
}
|
||||
7
webpack.dev.js
Normal file
7
webpack.dev.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const merge = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'development',
|
||||
devtool: '#cheap-source-map',
|
||||
})
|
||||
7
webpack.prod.js
Normal file
7
webpack.prod.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const merge = require('webpack-merge')
|
||||
const common = require('./webpack.common.js')
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'production',
|
||||
devtool: '#source-map'
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue