internet explorer - Webpack + Angular(4) + ES6 fungerer ikke på IE11
Jeg har undersøkt dette problemet ganske mye, og ærlig talt vet jeg ikke hva jeg skal prøve neste. Av en eller annen grunn kan ikke webpacken min kjøres i IE11 (den eneste IE jeg har prøvd), Safari på iPads med iOS 9.3.5 og noen Android-telefoner. Jeg er ikke sikker på om de alle har det samme problemet, men her viser jeg IE-en. Den faktiske feilen jeg får er SCRIPT1002: Syntax error:
"use strict";
eval("\r\nvar __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n};\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nconst core_1 = __webpack_require__(38);\r\nconst platform_browser_1 = __webpack_require__(92);\r\nconst app_component_1 = __webpack_require__(714);\r\nlet AppModule = class AppModule {\r\n};\r\nAppModule = __decorate([\r\n core_1.NgModule({\r\n bootstrap: [\r\n app_component_1.AppComponent,\r\n ],\r\n declarations: [\r\n app_component_1.AppComponent,\r\n ],\r\n imports: [\r\n platform_browser_1.BrowserModule,\r\n ],\r\n })\r\n], AppModule);\r\nexports.AppModule = AppModule;\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzEzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vc3JjL2FwcC9hcHAubW9kdWxlLnRzPzAwZmUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBCcm93c2VyTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXJcIjtcclxuaW1wb3J0IHsgQXBwQ29tcG9uZW50IH0gZnJvbSBcIi4vYXBwLmNvbXBvbmVudFwiO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBib290c3RyYXA6IFtcclxuICAgIEFwcENvbXBvbmVudCxcclxuICBdLFxyXG4gIGRlY2xhcmF0aW9uczogW1xyXG4gICAgQXBwQ29tcG9uZW50LFxyXG4gIF0sXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQnJvd3Nlck1vZHVsZSxcclxuICBdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXBwTW9kdWxlIHsgfVxyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gbm9kZV9tb2R1bGVzL2FuZ3VsYXIyLXRlbXBsYXRlLWxvYWRlciEuL25vZGVfbW9kdWxlcy90c2xpbnQtbG9hZGVyPz9yZWYtLTAhLi9zcmMvYXBwL2FwcC5tb2R1bGUudHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBYUE7QUFBQTtBQUFBO0FBWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///713\n");
Nå har jeg lekt med flere polyfills.ts, lagt til forskjellige pakker og imports som de som er foreslått i Tour of Heroes https://github.com/johnpapa/angular-tour-of-heroes/blob/master/src/polyfills.ts, men det ser ikke ut til å fungere. Jeg begynner å tro at det er et webpack-problem, men igjen, jeg kan mangle noe her. Jeg gjenskapte feilen i en enkel app med bare app-komponenten:
import { Component } from "@angular/core";
@Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent { }
app.module.ts:
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { AppComponent } from "./app.component";
@NgModule({
bootstrap: [
AppComponent,
],
declarations: [
AppComponent,
],
imports: [
BrowserModule,
],
})
export class AppModule { }
og dette fungerer fint på Chrome, FF og Safari på iPhones (iOS 10+). Jeg vet at noen mennesker ikke opplevde problemet på eldre versjoner av iOS, men som jeg sier, jeg er litt forvirret her og er ikke sikker på hvordan det er mulig).
Min packages.json er ganske enkel og tok det nyeste av pakkene for å få dette opp og gå raskt:
{
"name": "my-website",
"version": "1.0.0",
"description": "My Website",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 10209",
"postinstall": "typings install"
},
"author": "Me",
"license": "ISC",
"dependencies": {
"@angular/common": "4.3.5",
"@angular/compiler": "4.3.5",
"@angular/core": "4.3.5",
"@angular/platform-browser": "4.3.5",
"@angular/platform-browser-dynamic": "4.3.5",
"@angular/router": "4.3.5",
"classlist.js": "1.1.20150312",
"core-js": "2.5.0",
"intl": "1.2.5",
"mdn-polyfills": "5.0.0",
"rxjs": "5.4.3",
"web-animations-js": "2.3.1",
"zone.js": "0.8.16"
},
"devDependencies": {
"angular2-template-loader": "0.6.2",
"awesome-typescript-loader": "3.2.3",
"babel-minify": "0.2.0",
"css-loader": "0.28.5",
"extract-text-webpack-plugin": "3.0.0",
"file-loader": "0.11.2",
"html-loader": "0.5.1",
"html-webpack-plugin": "2.30.1",
"null-loader": "0.1.1",
"raw-loader": "0.5.1",
"rimraf": "2.6.1",
"style-loader": "0.18.2",
"to-string-loader": "1.1.5",
"tslint": "5.6.0",
"tslint-loader": "3.5.3",
"typescript": "2.4.2",
"typings": "2.1.1",
"url-loader": "0.5.9",
"webpack": "3.5.5",
"webpack-dev-server": "2.7.1",
"webpack-merge": "4.1.0"
}
}
Webpack-konfigurasjonen er, igjen, ganske enkel. webpack.common.js:
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const helpers = require('./helpers.js');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [{
test: /\.ts$/,
enforce: 'pre',
loader: 'tslint-loader',
options: {
emitErrors: true,
tsConfigFile: 'tsConfig.json',
configFile: 'tslint.json',
failOnHint: true
}
},
{
test: /\.ts$/,
loaders: [{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'tsconfig.json'
}
},
'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/images/[name].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
use: [{
loader: 'raw-loader'
}]
},
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html',
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('../src')
)
]
};
og webpack.dev.js:
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
publicPath: 'http://localhost:10209/',
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
});
Min vendor.ts er veldig standard:
// Angular
import "@angular/common";
import "@angular/core";
import "@angular/platform-browser";
import "@angular/platform-browser-dynamic";
import "@angular/router";
// RxJS
import "rxjs";
og det samme gjelder main.ts:
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
if (process.env.ENV === "production") {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);
Polyfills.ts-filen jeg bruker for øyeblikket:
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/* IE9, IE10 and IE11 requires all of the following polyfills. **/
import "core-js/es6/symbol";
// tslint:disable-next-line:ordered-imports
import "core-js/es6/object";
import "core-js/es6/function";
import "core-js/es6/parse-int";
// tslint:disable-next-line:ordered-imports
import "core-js/es6/parse-float";
import "core-js/es6/number";
// tslint:disable-next-line:ordered-imports
import "core-js/es6/math";
import "core-js/es6/string";
// tslint:disable-next-line:ordered-imports
import "core-js/es6/date";
import "core-js/es6/array";
import "core-js/es6/regexp";
// tslint:disable-next-line:ordered-imports
import "core-js/es6/map";
import "core-js/es6/set";
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// tslint:disable-next-line:align
// tslint:disable-next-line:ordered-imports
import "classlist.js"; // Run `npm install --save classlist.js`.
/* Evergreen browsers require these. **/
import "core-js/es6/reflect";
import "core-js/es7/reflect";
/**
* Required to support Web Animations `@angular/animation`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
*/
// tslint:disable-next-line:align
import "web-animations-js"; // Run `npm install --save web-animations-js`.
/***************************************************************************************************
* Zone JS is required by Angular itself.
*/
import "zone.js/dist/zone"; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
/**
* Date, currency, decimal and percent pipes.
* Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
*/
// tslint:disable-next-line:align
import "intl"; // Run `npm install --save intl`.
/**
* Need to import at least one locale-data with intl.
*/
// tslint:disable-next-line:align
import "intl/locale-data/jsonp/en";
Og til slutt index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<title>My website</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<my-app>
</my-app>
</body>
</html>
tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"exclude":[
"node_modules"
]
}
Nå er mitt spørsmål: Er det mulig å kjøre en bundlet app med webpack som retter seg mot ES6 på IE11 og noen av de andre nettleserne? Jeg har allerede søkt ganske mye, men dessverre har jeg ikke kommet over en fungerende løsning for dette. Jeg antar at hvis jeg kunne "feilsøke" webpack og se hvorfor det feiler, kunne jeg kanskje fått en bedre forståelse av det faktiske problemet, men jeg vet ikke hvordan jeg gjør det og om jeg kan gjøre det mot hvilken som helst nettleser.
Takk.
Svar #1
Jeg antar at du må legge til denne koden i polyfills.ts-filen din
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
Sjekk at du har lagt til alt. Det vil være nyttig i de fleste tilfeller. I prosjektet mitt i Angular2 måtte jeg legge til
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
til index.html. I Angular4 bør dette problemet være løst, men du kan prøve det.
