從0開始給Angular插上webpack的翅膀

引言:  Angular + Typescript + Webpack這套技術棧在工做中一直在用, 可是從0開始搭建起webpack的前端工程化基礎還歷來沒有本身作過, 遇到一些問題老是稀裏糊塗. 一直想從0開始搭建 angular的webpack打包工程.css

npm版本: v6.13.4 
node版本: v12.16.1html

根據 angular.io 上的建議作好初始化工程

npm install -g @angular/cli
ng new angular-webpack

生成了angular-webpack目錄, 可是此工程是用angular-cli來啓動的.前端

加入webpack.config.js 而且配置上entry和ouput

const path = require('path');
module.exports = {
    entry: { main: './src/main.ts', },
    output: {
        filename: '[name].[hash].js',
        path: path.resolve(__dirname, 'dist'),
    }
}

有webpack.config.js文件, 並不能直接使用, 須要安裝webpacknode

安裝webpack, webpack-cli, rimraf;package.json加上對應的打包scripts

npm install webpack webpack-cli rimraf --save-dev
/*package.json*/
"pack": "rimraf dist/\* && webpack",

試試打包看看webpack

執行npm run pack看看第一次打包效果:

ERROR in ./src/main.ts Module not found: Error: Can't resolve './app/app.module' in '/Users/chenhua/CodeBase/angular-webpack/src'  @ ./src/main.ts 4:0-45 10:41-50

webpack默認只會去解析js文件,因此尋找app.module.js沒找到就報錯, 而實際上咱們是app.module.ts文件web

加入resolve.extension配置, 讓webpack去"尋找"ts文件

resolve:{
    extensions:[  '.js', '.ts'],
}

運行再次報錯:typescript

ERROR in ./src/app/app.module.ts 8:0 Module parse failed: Unexpected character '@' (8:0)

緣由是@NgModule不能解析, 裝飾器語法 須要用typescript的loader來解析npm

加入awesome-typescript-loader

到此, 可以生成打包文件,下一個問題是怎麼把打包後的js放入index.html中?json

html-webpack-plugin動態生成html文件

使用html-webpack-plugin將output打包好的js文件,以script標籤的形式插入到一個index.html文件中,咱們須要咱們本身的index.html文件用於angular的啓動,因此給html-webpack-plugin配置上template.前端工程化

const HtmlWebpackPlugin = require( 'html-webpack-plugin');
plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html',
    }),
],

在瀏覽器中打開index.html,network顯示文件獲取不到bundle文件

file:///main.715b027541305761cdd9.js //如此獲取文件失敗

問題分析:直接打卡使用file協議請求, /bundle.js請求不到,

全局安裝http-server, npx, 執行npx htpp-server ./dist 目錄啓動, 訪問localhost:8080

Uncaught Error: Can't resolve all parameters for e: (?).  at Vt (main.715b027541305761cdd9.js:978) at e._getDependenciesMetadata (main.715b027541305761cdd9.js:1435) at e._getTypeMetadata (main.715b027541305761cdd9.js:1435) at e.getNgModuleMetadata (main.715b027541305761cdd9.js:1435) at e.getNgModuleSummary (main.715b027541305761cdd9.js:1435)

問題分析: webpack打包的時候自動進行了命名優化,看不出問題所在

加入mode: "development"

/*mode: "development"不會對打包文件進行命名優化, 因此可以看到更準確的問題*/
Uncaught Error: Can't resolve all parameters for ApplicationModule: (?).

問題分析:通過了解, 須要加入reflect的polyfills

手動加入pollyfills的entry,polyfills中加入reflect

entry: {
    polyfills: "./src/polyfills.ts",
    main: "./src/main.ts",
},
    
/*polyfills.ts中手動加入,core-js注意版本, 不然可能找不到es7/reflect,   core-js: 2.6.0*/
import 'core-js/es7/reflect';

配置polyfills以後,仍然報錯:

Unhandled Promise rejection: Failed to load app.component.html

問題分析: 由於沒有正確的打包到app.component.html,因此加入angular2-template-loader用於加載組件的template文件

配置angular2-template-loader

use:\[{ loader: 'angular2-template-loader', }\]
ERROR in ./src/app/app.component.html 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

問題分析: html文件缺乏對應的loader

配置html-loader

{
    test: /\.html?$/,
    use: [
        {
            loader: 'html-loader',
        }
    ],
},

繼續訪問,報錯:

compiler.js:6070 Uncaught Error: Expected 'styles' to be an array of strings.
   at assertArrayOfStrings (compiler.js:6070)
   at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:21995)
   at CompileMetadataResolver.\_getEntryComponentMetadata (compiler.js:22655)

問題分析: css文件沒有正確打包,

加入css文件對應的loader

{
    test: /\.css$/,
    use: ['to-string-loader', 'style-loader', 'css-loader'],
}

Bingo!!

屏幕快照 2020-03-10 下午4.59.53.png

相關文章
相關標籤/搜索