mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
stub out angular with webpack
This commit is contained in:
parent
848117ff86
commit
4d56d12ccb
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,5 +10,6 @@ webfonts/
|
|||||||
*.pem
|
*.pem
|
||||||
*.zip
|
*.zip
|
||||||
build/
|
build/
|
||||||
|
build2/
|
||||||
build.safariextension/
|
build.safariextension/
|
||||||
coverage/
|
coverage/
|
||||||
|
742
package-lock.json
generated
742
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@ -9,6 +9,8 @@
|
|||||||
"start:firefox": "web-ext run --source-dir ./dist/",
|
"start:firefox": "web-ext run --source-dir ./dist/",
|
||||||
"dev": "gulp build && webpack --config webpack.dev.js",
|
"dev": "gulp build && webpack --config webpack.dev.js",
|
||||||
"dev:watch": "gulp build && webpack --config webpack.dev.js --watch",
|
"dev:watch": "gulp build && webpack --config webpack.dev.js --watch",
|
||||||
|
"dev2": "webpack --config webpack2.js",
|
||||||
|
"dev2:watch": "webpack --config webpack2.js --watch",
|
||||||
"prod": "gulp build && webpack --config webpack.prod.js",
|
"prod": "gulp build && webpack --config webpack.prod.js",
|
||||||
"dist": "npm run prod && gulp dist",
|
"dist": "npm run prod && gulp dist",
|
||||||
"dist:firefox": "npm run prod && gulp dist:firefox",
|
"dist:firefox": "npm run prod && gulp dist:firefox",
|
||||||
@ -20,7 +22,18 @@
|
|||||||
"test:watch": "karma start"
|
"test:watch": "karma start"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@ngtools/webpack": "1.10.2",
|
||||||
|
"@types/angular": "^1.6.34",
|
||||||
|
"@types/chrome": "0.0.51",
|
||||||
"@types/jasmine": "^2.8.2",
|
"@types/jasmine": "^2.8.2",
|
||||||
|
"@types/jquery": "^3.2.16",
|
||||||
|
"@types/lunr": "2.1.5",
|
||||||
|
"@types/node-forge": "0.6.10",
|
||||||
|
"@types/papaparse": "4.1.31",
|
||||||
|
"@types/safari-extension": "^0.0.27",
|
||||||
|
"@types/safari-extension-content": "^0.0.14",
|
||||||
|
"@types/tldjs": "1.7.1",
|
||||||
|
"@types/webcrypto": "^0.0.28",
|
||||||
"angular": "1.6.9",
|
"angular": "1.6.9",
|
||||||
"angular-animate": "1.6.9",
|
"angular-animate": "1.6.9",
|
||||||
"angular-sweetalert": "1.1.2",
|
"angular-sweetalert": "1.1.2",
|
||||||
@ -59,11 +72,11 @@
|
|||||||
"karma-typescript": "^3.0.8",
|
"karma-typescript": "^3.0.8",
|
||||||
"less": "^3.0.0-alpha.3",
|
"less": "^3.0.0-alpha.3",
|
||||||
"less-loader": "^4.0.5",
|
"less-loader": "^4.0.5",
|
||||||
"lunr": "2.1.6",
|
|
||||||
"ng-infinite-scroll": "1.3.0",
|
"ng-infinite-scroll": "1.3.0",
|
||||||
"ngclipboard": "1.1.1",
|
"ngclipboard": "1.1.1",
|
||||||
"node-forge": "0.7.1",
|
"node-sass": "^4.7.2",
|
||||||
"papaparse": "4.3.5",
|
"papaparse": "4.3.5",
|
||||||
|
"sass-loader": "^6.0.6",
|
||||||
"style-loader": "^0.19.0",
|
"style-loader": "^0.19.0",
|
||||||
"sweetalert": "1.1.3",
|
"sweetalert": "1.1.3",
|
||||||
"tldjs": "2.0.0",
|
"tldjs": "2.0.0",
|
||||||
@ -76,16 +89,23 @@
|
|||||||
"webpack-merge": "^4.1.0"
|
"webpack-merge": "^4.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/angular": "^1.6.34",
|
"@angular/animations": "5.2.0",
|
||||||
"@types/chrome": "0.0.51",
|
"@angular/common": "5.2.0",
|
||||||
"@types/jquery": "^3.2.16",
|
"@angular/compiler": "5.2.0",
|
||||||
"@types/lunr": "2.1.5",
|
"@angular/core": "5.2.0",
|
||||||
"@types/node-forge": "0.6.10",
|
"@angular/forms": "5.2.0",
|
||||||
"@types/papaparse": "4.1.31",
|
"@angular/http": "5.2.0",
|
||||||
"@types/safari-extension": "^0.0.27",
|
"@angular/platform-browser": "5.2.0",
|
||||||
"@types/safari-extension-content": "^0.0.14",
|
"@angular/platform-browser-dynamic": "5.2.0",
|
||||||
"@types/tldjs": "1.7.1",
|
"@angular/router": "5.2.0",
|
||||||
"@types/webcrypto": "^0.0.28",
|
"@angular/upgrade": "5.2.0",
|
||||||
"@uirouter/angularjs": "^1.0.10"
|
"@uirouter/angularjs": "^1.0.10",
|
||||||
|
"angular2-toaster": "4.0.2",
|
||||||
|
"angulartics2": "5.0.1",
|
||||||
|
"core-js": "2.4.1",
|
||||||
|
"lunr": "2.1.6",
|
||||||
|
"node-forge": "0.7.1",
|
||||||
|
"rxjs": "5.5.6",
|
||||||
|
"zone.js": "0.8.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
"webRequest",
|
"webRequest",
|
||||||
"webRequestBlocking"
|
"webRequestBlocking"
|
||||||
],
|
],
|
||||||
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||||
"commands": {
|
"commands": {
|
||||||
"autofill_login": {
|
"autofill_login": {
|
||||||
"suggested_key": {
|
"suggested_key": {
|
||||||
|
3
src/popup2/accounts/login.component.html
Normal file
3
src/popup2/accounts/login.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<form id="login-page" #form>
|
||||||
|
Login Form
|
||||||
|
</form>
|
44
src/popup2/accounts/login.component.ts
Normal file
44
src/popup2/accounts/login.component.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import * as template from './login.component.html';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
ComponentFactoryResolver,
|
||||||
|
ViewChild,
|
||||||
|
ViewContainerRef,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
import { Angulartics2 } from 'angulartics2';
|
||||||
|
|
||||||
|
import { AuthResult } from 'jslib/models/domain/authResult';
|
||||||
|
|
||||||
|
import { AuthService } from 'jslib/abstractions/auth.service';
|
||||||
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
import { SyncService } from 'jslib/abstractions/sync.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
template: template,
|
||||||
|
})
|
||||||
|
export class LoginComponent {
|
||||||
|
@ViewChild('environment', { read: ViewContainerRef }) environmentModal: ViewContainerRef;
|
||||||
|
|
||||||
|
email: string = '';
|
||||||
|
masterPassword: string = '';
|
||||||
|
showPassword: boolean = false;
|
||||||
|
formPromise: Promise<AuthResult>;
|
||||||
|
|
||||||
|
constructor(private router: Router, private analytics: Angulartics2,
|
||||||
|
private toasterService: ToasterService) { }
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
togglePassword() {
|
||||||
|
this.analytics.eventTrack.next({ action: 'Toggled Master Password on Login' });
|
||||||
|
this.showPassword = !this.showPassword;
|
||||||
|
document.getElementById('masterPassword').focus();
|
||||||
|
}
|
||||||
|
}
|
21
src/popup2/app-routing.module.ts
Normal file
21
src/popup2/app-routing.module.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import {
|
||||||
|
RouterModule,
|
||||||
|
Routes,
|
||||||
|
} from '@angular/router';
|
||||||
|
|
||||||
|
import { LoginComponent } from './accounts/login.component';
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: '', redirectTo: '/login', pathMatch: 'full' },
|
||||||
|
{ path: 'login', component: LoginComponent },
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forRoot(routes, {
|
||||||
|
useHash: true,
|
||||||
|
/*enableTracing: true,*/
|
||||||
|
})],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class AppRoutingModule { }
|
39
src/popup2/app.component.ts
Normal file
39
src/popup2/app.component.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
ToasterConfig,
|
||||||
|
ToasterContainerComponent,
|
||||||
|
} from 'angular2-toaster';
|
||||||
|
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
ComponentFactoryResolver,
|
||||||
|
NgZone,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
Type,
|
||||||
|
ViewChild,
|
||||||
|
ViewContainerRef,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
import { Angulartics2 } from 'angulartics2';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
styles: [],
|
||||||
|
template: `
|
||||||
|
<toaster-container [toasterconfig]="toasterConfig"></toaster-container>
|
||||||
|
<router-outlet></router-outlet>`,
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
toasterConfig: ToasterConfig = new ToasterConfig({
|
||||||
|
showCloseButton: true,
|
||||||
|
mouseoverTimerStop: true,
|
||||||
|
animation: 'flyRight',
|
||||||
|
limit: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics, private analytics: Angulartics2,
|
||||||
|
private toasterService: ToasterService) { }
|
||||||
|
}
|
1
src/popup2/app.d.ts
vendored
Normal file
1
src/popup2/app.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
declare module '*.html';
|
44
src/popup2/app.module.ts
Normal file
44
src/popup2/app.module.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import 'core-js';
|
||||||
|
import 'zone.js/dist/zone';
|
||||||
|
|
||||||
|
import { ToasterModule } from 'angular2-toaster';
|
||||||
|
import { Angulartics2Module } from 'angulartics2';
|
||||||
|
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
|
||||||
|
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
import { ServicesModule } from './services/services.module';
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
import { LoginComponent } from './accounts/login.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
FormsModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
ServicesModule,
|
||||||
|
Angulartics2Module.forRoot([Angulartics2GoogleAnalytics], {
|
||||||
|
pageTracking: {
|
||||||
|
clearQueryParams: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
ToasterModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
LoginComponent,
|
||||||
|
],
|
||||||
|
entryComponents: [
|
||||||
|
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [AppComponent],
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
14
src/popup2/index.html
Normal file
14
src/popup2/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Bitwarden</title>
|
||||||
|
<base href="">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root>
|
||||||
|
<div id="loading"><i class="fa fa-spinner fa-spin fa-3x"></i></div>
|
||||||
|
</app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
src/popup2/main.ts
Normal file
15
src/popup2/main.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
|
require('../scss/popup.scss');
|
||||||
|
// tslint:disable-next-line
|
||||||
|
require('../scripts/duo.js');
|
||||||
|
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
//if (!isDev()) {
|
||||||
|
// enableProdMode();
|
||||||
|
//}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
31
src/popup2/services/auth-guard.service.ts
Normal file
31
src/popup2/services/auth-guard.service.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
CanActivate,
|
||||||
|
Router,
|
||||||
|
} from '@angular/router';
|
||||||
|
|
||||||
|
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
||||||
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
|
import { UserService } from 'jslib/abstractions/user.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthGuardService implements CanActivate {
|
||||||
|
constructor(private cryptoService: CryptoService, private userService: UserService, private router: Router,
|
||||||
|
private messagingService: MessagingService) { }
|
||||||
|
|
||||||
|
async canActivate() {
|
||||||
|
const isAuthed = await this.userService.isAuthenticated();
|
||||||
|
if (!isAuthed) {
|
||||||
|
this.messagingService.send('logout');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = await this.cryptoService.getKey();
|
||||||
|
if (key == null) {
|
||||||
|
this.router.navigate(['lock']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
33
src/popup2/services/broadcaster.service.ts
Normal file
33
src/popup2/services/broadcaster.service.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BroadcasterService {
|
||||||
|
subscribers: Map<string, (message: any) => any> = new Map<string, (message: any) => any>();
|
||||||
|
|
||||||
|
send(message: any, id?: string) {
|
||||||
|
if (id != null) {
|
||||||
|
if (this.subscribers.has(id)) {
|
||||||
|
this.subscribers.get(id)(message);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscribers.forEach((value) => {
|
||||||
|
value(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(id: string, messageCallback: (message: any) => any) {
|
||||||
|
if (this.subscribers.has(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscribers.set(id, messageCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsubscribe(id: string) {
|
||||||
|
if (this.subscribers.has(id)) {
|
||||||
|
this.subscribers.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/popup2/services/services.module.ts
Normal file
35
src/popup2/services/services.module.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import {
|
||||||
|
APP_INITIALIZER,
|
||||||
|
NgModule,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
import { ToasterModule } from 'angular2-toaster';
|
||||||
|
|
||||||
|
import { AuthGuardService } from './auth-guard.service';
|
||||||
|
import { BroadcasterService } from './broadcaster.service';
|
||||||
|
import { ValidationService } from './validation.service';
|
||||||
|
|
||||||
|
function initFactory(): Function {
|
||||||
|
return async () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
ToasterModule,
|
||||||
|
],
|
||||||
|
declarations: [],
|
||||||
|
providers: [
|
||||||
|
ValidationService,
|
||||||
|
AuthGuardService,
|
||||||
|
{
|
||||||
|
provide: APP_INITIALIZER,
|
||||||
|
useFactory: initFactory,
|
||||||
|
deps: [],
|
||||||
|
multi: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class ServicesModule {
|
||||||
|
}
|
37
src/popup2/services/validation.service.ts
Normal file
37
src/popup2/services/validation.service.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
|
||||||
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ValidationService {
|
||||||
|
constructor(private toasterService: ToasterService, private i18nService: I18nService) { }
|
||||||
|
|
||||||
|
showError(data: any): string[] {
|
||||||
|
const defaultErrorMessage = this.i18nService.t('unexpectedError');
|
||||||
|
const errors: string[] = [];
|
||||||
|
|
||||||
|
if (data == null || typeof data !== 'object') {
|
||||||
|
errors.push(defaultErrorMessage);
|
||||||
|
} else if (data.validationErrors == null) {
|
||||||
|
errors.push(data.message ? data.message : defaultErrorMessage);
|
||||||
|
} else {
|
||||||
|
for (const key in data.validationErrors) {
|
||||||
|
if (!data.validationErrors.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.validationErrors[key].forEach((item: string) => {
|
||||||
|
errors.push(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length > 0) {
|
||||||
|
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), errors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
3
src/scss/popup.scss
Normal file
3
src/scss/popup.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
body {
|
||||||
|
color: black;
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"target": "ES2016",
|
"target": "ES2016",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
@ -20,6 +22,7 @@
|
|||||||
"dist",
|
"dist",
|
||||||
"jslib/dist",
|
"jslib/dist",
|
||||||
"build",
|
"build",
|
||||||
|
"build2",
|
||||||
"build.safariextension",
|
"build.safariextension",
|
||||||
"coverage",
|
"coverage",
|
||||||
"store",
|
"store",
|
||||||
|
150
webpack2.js
Normal file
150
webpack2.js
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||||
|
|
||||||
|
const isVendorModule = (module) => {
|
||||||
|
if (!module.context) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeModule = module.context.indexOf('node_modules') !== -1;
|
||||||
|
const bitwardenModule = module.context.indexOf('@bitwarden') !== -1;
|
||||||
|
return nodeModule && !bitwardenModule;
|
||||||
|
};
|
||||||
|
|
||||||
|
const extractCss = new ExtractTextPlugin({
|
||||||
|
filename: '[name].css',
|
||||||
|
disable: false,
|
||||||
|
allChunks: true
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
'popup/main': './src/popup2/main.ts',
|
||||||
|
'background': './src/background.ts',
|
||||||
|
'content/autofill': './src/content/autofill.js',
|
||||||
|
'content/autofiller': './src/content/autofiller.js',
|
||||||
|
'content/notificationBar': './src/content/notificationBar.js',
|
||||||
|
'content/shortcuts': './src/content/shortcuts.js',
|
||||||
|
'downloader/downloader': './src/downloader/downloader.ts',
|
||||||
|
'2fa/2fa': './src/2fa/2fa.ts',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.ts$/,
|
||||||
|
enforce: 'pre',
|
||||||
|
loader: 'tslint-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
exclude: /node_modules\/(?!(@bitwarden)\/).*/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(html)$/,
|
||||||
|
loader: 'html-loader'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
|
||||||
|
exclude: /loading.svg/,
|
||||||
|
use: [{
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]',
|
||||||
|
outputPath: 'popup/fonts/',
|
||||||
|
publicPath: './fonts/'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(jpe?g|png|gif|svg)$/i,
|
||||||
|
exclude: /.*(fontawesome-webfont|glyphicons-halflings-regular)\.svg/,
|
||||||
|
use: [{
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]',
|
||||||
|
outputPath: 'popup/images/',
|
||||||
|
publicPath: './images/'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: extractCss.extract({
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: 'sass-loader',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
publicPath: '../'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CleanWebpackPlugin([
|
||||||
|
path.resolve(__dirname, 'build2/*')
|
||||||
|
]),
|
||||||
|
// ref: https://github.com/angular/angular/issues/20357
|
||||||
|
new webpack.ContextReplacementPlugin(
|
||||||
|
/\@angular(\\|\/)core(\\|\/)esm5/,
|
||||||
|
path.resolve(__dirname, './src')
|
||||||
|
),
|
||||||
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
|
name: 'popup/vendor',
|
||||||
|
chunks: ['popup/main'],
|
||||||
|
minChunks: isVendorModule
|
||||||
|
}),
|
||||||
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
|
name: 'vendor',
|
||||||
|
chunks: ['background'],
|
||||||
|
minChunks: isVendorModule
|
||||||
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/popup2/index.html',
|
||||||
|
filename: 'popup/index.html',
|
||||||
|
chunks: ['popup/vendor', 'popup/main', 'fonts']
|
||||||
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/background.html',
|
||||||
|
filename: 'background.html',
|
||||||
|
chunks: ['vendor', 'background']
|
||||||
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/downloader/index.html',
|
||||||
|
filename: 'downloader/index.html',
|
||||||
|
chunks: ['downloader/downloader']
|
||||||
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/2fa/index.html',
|
||||||
|
filename: '2fa/index.html',
|
||||||
|
chunks: ['2fa/2fa']
|
||||||
|
}),
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
'./src/manifest.json',
|
||||||
|
{ from: './src/_locales', to: '_locales' },
|
||||||
|
{ from: './src/edge', to: 'edge' },
|
||||||
|
{ from: './src/safari', to: 'safari' },
|
||||||
|
{ from: './src/images', to: 'images' },
|
||||||
|
{ from: './src/content/autofill.css', to: 'content' }
|
||||||
|
]),
|
||||||
|
extractCss
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js'],
|
||||||
|
alias: {
|
||||||
|
jslib: path.join(__dirname, 'jslib/src')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.resolve(__dirname, 'build2')
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user