webpack構建多頁面react項目(webpack+typescript+react)

 目錄介紹javascript

  src:裏面的每一個文件夾就是一個頁面,頁面開發相關的組件、圖片和樣式文件就存放在對應的文件夾下。css

  tpl:裏面放置模板文件,當webpack打包時爲html-webpack-plugin插件提供模板。html

  tsconfig.json:typescript的配置文件,須要本身新建並編寫。java

  webpack.config.js:webpack的配置文件,須要本身新建並編寫。node

  config:文件夾下的index.dev.js用來配置開發模塊,index.js配置發佈模塊。將會在webpack.config.js中引用。index.dev.js是index.js的子集,index.js包含了全部的頁面。react

 index.dev.jswebpack

module.exports = {
    page2: {
        title: "hello world!",
        tpl: "index"
      }
};

index.jscss3

module.exports = {
    page1: {
      title: "hello world!",
      tpl: "index"
    },
    page2: {
      title: "hello world!",
      tpl: "index"
    }
  };
  

 

npm初始化項目web

  執行npm init命令,填寫完基本信息後會生成一個package.json文件,"dependencies"屬性是在安裝依賴包附帶--save參數時生成的,「devDependencies」屬性是在安裝開發依賴包附帶--save-dev參數時生成的。typescript

npm init

package.json文件

{
  "name": "react-demo",
  "version": "1.0.0",
  "description": "react+typescript+webpack項目",
  "private": true,  //設置爲true,那麼npm將拒絕發佈它,防止私人存儲庫意外發布
  "scripts": {      // 自定義腳本,經過npm run執行腳本
    "start": "webpack-dev-server --mode development --cfg dev",  //啓動web服務器,cfg是自定義參數,賦值爲dev。
    "build": "webpack --mode production"
  },
  "keywords": [
    "react",
    "typescript",
    "webpack"
  ],
  "author": "chencong",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "ts-loader": "^5.3.3",
    "typescript": "^3.3.3",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.1.14",
    "yargs": "^13.1.0"
  },
  "dependencies": {
    "react": "^16.8.2",
    "react-dom": "^16.8.2"
  }
}

 

添加react

npm install --save react react-dom

 

添加typescript

安裝typescript編譯器和loader

npm install --save-dev typescript ts-loader

   安裝完成後須要編寫配置文件,在項目中新建tsconfig.json文件。配置完後就該ts-loader登場了,在webpack.config.js中配置loader,將項目中全部的用typescript語法編寫的文件都用ts-loader處理,處理的依據就是tsconfig.json文件。還有一點須要提一下,項目能夠不用babel進行轉碼了,由於ts-loader已經幫咱們處理了,tsconfig.json中「target」: 「es5」就是轉碼成es5的配置,"jsx": "react"就是對jsx的支持,不須要用babel-preset-react進行轉碼。(typescript配置文檔)

{
  "version": "1.0.0",
  "compilerOptions": {
    "baseUrl": "./",  //解析非相對模塊的基準目錄
    "paths": {  //路徑映射,如在文件中使用‘~/’至關於‘src/’
      "~/*": ["src/*"]
    },
    "module": "esnext",  //指定生成哪一個模塊系統的代碼
    "target": "es5", //生成es5的js文件
    "jsx": "react",  //在tsx文件裏支持jsx
    "sourceMap": true,
    "moduleResolution": "node", //決定如何處理模塊
    "allowJs": true,  //容許編譯js文件
    "strictNullChecks": false,  //在嚴格的 null檢查模式下, null和 undefined值不包含在任何類型裏,只容許用它們本身和 any來賦值(有個例外, undefined能夠賦值到 void)
    "lib": ["es2015", "dom", "es2015.promise"]  //編譯過程當中須要引入的庫文件的列表
  },
  "include": ["src/**/*"], //編譯包含在  src及其子目錄下的全部匹配的文件
  "exclude": ["dist", "node_modules"]  //編譯時排除 dist、node_modules文件夾
}

 

添加webpack

  執行如下命令添加webpack,使用webpack 4.X的命令行須要單獨安裝命令行工具,因此也要安裝webpack-cli。html-webpack-plugin插件幫助咱們在打包時根據模板生成html文件,還需注意模板中title標籤的寫法,應爲<title><%= htmlWebpackPlugin.options.title%></title>。clean-webpack-plugin插件會在項目打包前刪除指定的文件,一般用來刪除舊的打包文件。yargs包提供了獲取命令行中參數的對象。

npm install --save-dev webpack webpack-cli html-webpack-plugin clean-webpack-plugin yargs

接下來編寫webpack的配置文件,在項目中新建配置文件webpack.config.js。(webpack文檔)

const path = require("path");
const argv = require("yargs").argv;  //獲取命令行中參數的對象
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");

const isDev = argv.cfg && argv.cfg === "dev";  //是否爲開發模式,若是輸入yarn start執行"webpack-dev-server --mode development --cfg dev",argv.cfg獲取參數的值爲dev。
let compileConfig = "index";
if (isDev) {
  compileConfig = "index." + argv.cfg;
}

const buildConfig = require(`./config/${compileConfig}`); // 開發模式下,引入index.dev.js中的配置信息。生產模式下,引入index.js中的配置信息
const modules = Object.keys(buildConfig);
const entry = Object.create(null);
const htmlPlugins = [];
if (modules.length > 0) {
  for (let srcModule of modules) {
    entry[srcModule] = path.resolve(__dirname, `./src/${srcModule}`);  // 多頁面應用webpack配置文件entry屬性的值
    htmlPlugins.push(  // html-webpack-plugin插件生成html的配置 new HtmlWebpackPlugin({
        title: buildConfig[srcModule]["title"],
        filename: `${srcModule}/index.html`,
        template: path.resolve(__dirname, "./tpl/index.html"),
        chunks: [srcModule]
      })
    );
  }
}

const config = {
  entry,
  output: {
    publicPath: "/dist/",
    filename: "[name].[hash].js",
    path: path.resolve(__dirname, "dist")
  },
  module: {
   rules: [
    { // 除了node_modules文件夾中的文件,全部的tsx文件都用ts-loader處理
     test: /\.tsx?$/,
     use: "ts-loader",
     exclude: /node_modules/
    }
   ] 
} plugins: [
new CleanPlugin(['dist']), ...htmlPlugins], resolve: { extensions: [".tsx", ".ts", ".js"] }, devtool: isDev ? "source-map" : false // 值爲source-map時,方便在瀏覽器中使用react開發工具調試 }; if (isDev) { // 開發模式時,啓動web服務 config.devServer = {
  contentBase: './dist', // 告訴服務器那個文件夾提供靜態資源 port:
9000, open: true, hot: false, // 啓用webpack中的熱替換特性,這裏咱們不用熱替換(不刷新整個頁面的狀況下更新部分更改)而用熱更新(整個頁面自動刷新) openPage: `dist/${modules[0]}` // 打開index.dev.js配置中的第一個頁面 }; // config.plugins.push(new webpack.HotModuleReplacementPlugin()); // 熱替換須要的插件 } module.exports = config;

 

關於樣式

  webpack在打包除javascript之外的靜態資源時,須要用loader預處理。在實際開發中我一般用less來寫樣式,因此先要用less將less文件編譯成css ,而後用css-loader預處理css文件。最後還須要用mini-css-extract-plugin插件將css從webpack打包後的文件中抽離出來按需加載,或者用style-loader將css之內聯的方式加載,mini-css-extract-plugin插件和style-loader不能同時使用,推薦使用前者將樣式抽離出來按需加載。

安裝

npm install --save-dev css-loader less-loader less mini-css-extract-plugin

webpack.config.js中配置

  module: {
    rules: [
       ...
      {
        test: /\.less$/,
        use: [  // webpack會從右往左加載loader,全部書寫loader時有順序要求 // {
    //  loader: 'style-loader' //style-loader不能和mini-css-extract-plugin同時使用
    // }
MiniCssExtractPlugin.loader, {
        loader: 'css-loader'
      },
{
        loader: 'less-loader'
      }
] } ... ] }, plugins: [ ... new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[name].[hash].css" }), ... ],

autoprefixer

  寫樣式時爲了兼容不一樣的瀏覽器,css3的特性須要加前綴,例如:

-moz-  對應  Firefox, 
-webkit-  對應  Safari and Chrome
-o-  對應  Opera
-ms-  對應  Internet Explorer

若是本身手動地寫就會很麻煩,因而就有了autoprofixer幫咱們自動添加這些前綴。postcss-flexbugs-fixe是用來修復一些flexbox的bug。

安裝

cnpm install --save-dev postcss-loader autoprefixer postcss-flexbugs-fixes

webpack.config.js中配置

  module: {
    rules: [
       ...
      {
        test: /\.less$/,
        use: [
          // {
          //   loader: "style-loader" 
          // },
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader"
          },
          {
            loader: "less-loader"
          },
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss",  // postcss-loader中options裏使用了function、require時須要ident屬性,能夠是任意值
              plugins: () => [
                require("postcss-flexbugs-fixes"),
                autoprefixer({
                  browsers: [
                    ">1%",
                    "last 4 versions",
                    "Firefox ESR",
                    "not ie < 9"
                  ],
                  flexbox: "no-2009"  // false將禁用flexbox屬性前綴。或flexbox:「no-2009」將僅爲最終版本和IE版本的規範添加前綴。
                })
              ]
            }
          },
        ]
      }
    ]
  },    

 

圖片處理 

  頁面引入圖片如:background: url(,/images/logo.png)  ,webpack打包時沒法解析圖片報錯,這時就須要loader來處理圖片。

ur-loader能夠將圖片轉化成base64的格式,以減小請求次數。。

安裝

npm i -D url-loader

webpack.config.js配置

module: {
  rules: [
    ...
    {
        test: /\.png|jpg|gif|jpeg|svg/,
        use: [
            {
                loader: 'url-loader',
                options: {
                    limit: 10000,   // 當圖片小於limit(單位:byte)時圖片轉換成base64,大於limit時其表現行爲等於file-loader
                  name: './images/[name].[hash:8].[ext]'   // 當圖片大於limit時起做用 ,'./images'表示圖片打包的路徑相對於output.path,[name]表示圖片的名稱,[hash:8]表示9位數的hash值,[ext]表示保持原來的後綴名
         } } ] } ] }

  以上就是構建多頁面應用的全部配置了,若有疑問或有更好的建議歡迎交流!

相關文章
相關標籤/搜索