webpack 4 :從0配置到項目搭建

webpack4發佈以來,我寫項目都是用腳手架,即便再簡單的項目,真的是really shame。。雖然道聽途說了不少 webpack4 的特性,卻沒有嘗試過,由於它給人的感受就是,em...很難。可是今天我從最簡單的部分開始,一點點搭建起一個項目。css

0配置,配置了什麼

讓咱們從0開始,新建一個項目,在終端執行如下語句:html

mkdir webpack-4-quickstart && cd webpack-4-quickstart
npm init -y
npm i webpack --save-dev
npm i webpack-cli --save-dev
複製代碼

修改代碼 package.jsonscripts 部分:vue

"scripts": {
  "build": "webpack"
}
複製代碼

如今,咱們的 package.json 是這樣的:node

{
  "name": "webpack-4-quickstart",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.14.0",
    "webpack-cli": "^3.0.8"
  }
}
複製代碼

此時,咱們執行 npm run build, 會給出如下提示/錯誤:react

webpack4-error

  1. error: 沒有入口文件
  2. warning: 建議設置 mode 選項

entry & output

爲了解決第一個問題,咱們嘗試新建 src/index.js:webpack

console.log(`I'm a entry point`);
複製代碼

此時再次執行 npm run build,成功打包出了 dist/main.js,所以咱們能夠得知:git

webpack4 more配置了 entry(入口) src/index.js 和output(出口) dist/main.jsgithub

固然,若是你想覆蓋這個配置(好比修改成 ./foo/src/js/index.js),能夠在 package.json 修改:web

"scripts": {
  "dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js",
  "build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}
複製代碼

production & development

webpack4 以前,咱們寫一個項目起碼會設置兩種類型文件:vue-cli

  • 用於開發環境的webpack.dev.conf.js,定義 webpack 啓動的服務器等
  • 用於生產環境的webpack.prod.conf.js,定義UglifyJSPlugin或其餘配置等

而 webpack4 的 mode 給出了兩種配置:developmentproduction

咱們修改 package.jsonscripts 部分:

"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}
複製代碼

咱們分別執行 npm run devnpm run build

webpack4-mode

執行 npm run dev 打包的是未壓縮的代碼,而 npm run build 是壓縮後的代碼。

  • 生產模式下:啓用了 代碼壓縮、做用域提高(scope hoisting)、 tree-shaking,使代碼最精簡
  • 開發模式下:相較於更小體積的代碼,提供的是打包速度上的優化

總結

webpack 4 的零配置主要應用於:

  • entry 默認設置爲 ./src/index.js
  • output 默認設置爲 ./dist/main.js
  • productiondevelopment 兩種模式

項目搭建

項目搭建,咱們對webpack的訴求是:

  • js的處理:轉換 ES6 代碼,解決瀏覽器兼容問題
  • css的處理:編譯css,自動添加前綴,抽取css到獨立文件
  • html的處理:複製並壓縮html文件
  • dist的清理:打包前清理源目錄文件
  • assets的處理:靜態資源處理
  • server的啓用:development 模式下啓動服務器並實時刷新

轉換 ES6 代碼,解決瀏覽器兼容問題

用 babel 轉換 ES6 代碼

用 babel 轉換 ES6 代碼須要使用到 babel-loader ,咱們須要安裝一系列的依賴:

npm i babel-core babel-loader babel-preset-env --save-dev
複製代碼

而後在根目錄新建一個babel配置文件 .babelrc

{
        "presets": [
            "env"
        ]
    }
複製代碼

那麼如何將配置用於webpack打包中?

  • 新建一個 webpack 的配置文件
  • 在 npm scripts 中使用 --module-bind
  1. 使用 webpack 的配置文件的方法:

    新建 webpack.config.js

    module.exports = {
          module: {
            rules: [
              {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader"
                }
              }
            ]
          }
        }
    複製代碼
  2. 在 npm scripts 中配置的方法:

"scripts": {
      "dev": "webpack --mode development --module-bind js=babel-loader",
      "build": "webpack --mode production --module-bind js=babel-loader"
    }
複製代碼

使用 babel-polyfill 解決兼容性問題

然而瀏覽器依然不支持一些語法的使用,致使兼容性問題,咱們用 babel-polyfill 解決:

npm i babel-polyfill babel-plugin-transform-runtime  --save-dev
複製代碼

.babelrc 添加配置:

{
    "presets": [
        "env"
    ],
    "plugins": [
       "transform-runtime"
    ]
}
複製代碼

最後在 webpack.config.js 中將 babel-polyfill 加到你的 entry 數組中:

const path = require('path');
module.exports = {
    entry: [
        "babel-polyfill",
        path.join(__dirname, './src/index.js')
    ],
    // ...
};
複製代碼

編譯css,自動添加前綴,抽取css到獨立文件

webpack 並不會主動將你的css代碼提取到一個文件,過去咱們使用 extract-text-webpack-plugin,在webpack4中咱們使用mini-css-extract-plugin來解決這個問題。

postcss-loader 用於添加瀏覽器前綴,相關配置我喜歡在根目錄新建 postcss.config.js 配置

npm i mini-css-extract-plugin css-loader --save-dev
    npm i style-loader postcss-loader  --save-dev
複製代碼
// webpack.config.js
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    module.exports = (env, argv) => {
      const devMode = argv.mode !== 'production'
      return {
        module: {
          rules: [
            // ...,
            {
                test: /\.css$/,
                use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },
            ]
          },
          plugins: [
            // ...,
            new MiniCssExtractPlugin({
              filename: "[name].css",
              chunkFilename: "[id].css"
            })
          ]
      }
    }
複製代碼
// postcss.config.js
    module.exports = {
        plugins: {
            autoprefixer: {}
        }
    }
複製代碼

複製並壓縮html文件 html-webpack-plugin

npm i html-webpack-plugin html-loader --save-dev
複製代碼
// webpack.config.js
    const HtmlWebPackPlugin = require("html-webpack-plugin");
    module.exports = {
        module: {
            rules: [
                // ...,
                {
                    test: /\.html$/,
                    use: [{
                        loader: "html-loader",
                        options: {
                            minimize: true
                        }
                    }]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: "./src/index.html",
                filename: "./index.html"
            })
        ]
    };
複製代碼

打包前清理源目錄文件 clean-webpack-plugin

每次打包,都會生成項目的靜態資源,隨着某些文件的增刪,咱們的 dist 目錄下可能產生一些再也不使用的靜態資源,webpack並不會自動判斷哪些是須要的資源,爲了避免讓這些舊文件也部署到生產環境上佔用空間,因此在 webpack 打包前最好能清理 dist 目錄。

npm install clean-webpack-plugin --save-dev
複製代碼
const CleanWebpackPlugin = require('clean-webpack-plugin');
  module.exports = {
    plugins: [
      new CleanWebpackPlugin(['dist']),
    ]
  };
複製代碼

靜態資源處理 file-loader

npm install file-loader --save-dev
複製代碼
// webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: 'file-loader',
                options: {}
              }
            ]
          }
        ]
      }
    }
複製代碼

development 模式下啓動服務器並實時刷新 webpack-dev-server

npm i webpack-dev-server --save-dev
複製代碼

package.json

"scripts": {
      "start": "webpack-dev-server --mode development --open",
      "build": "webpack --mode production"
    }
複製代碼

使用 webpack 4 創建 react 項目

如今咱們模仿 create-react-app 的結構,本身搭建一個 react 項目,而且用less預編譯:

├── public
  │   └── index.html      # html 模板
  ├── src
  │   ├── assets          # 靜態資源
  │   │   └── logo.png
  │   ├── components      # 組件
  │   │   └── App.js
  │   ├── index.js        # 入口文件
  │   └── styles
  │       └── index.less
  ├── .babelrc
  ├── package-lock.json
  ├── package.json
  ├── postcss.config.js
  └── webpack.config.js
複製代碼

在以上的基礎(項目搭建部分),再安裝react相關模塊及less模塊:

npm i react react-dom --save
    npm i babel-preset-react --save-dev
    npm i less less-loader --save-dev
複製代碼

修改 .babelrc:

{
      "presets": ["env", "react"]
    }
複製代碼

修改 webpack.config.js

// webpack.config.js
    const path = require('path');
    module.exports = (env, argv) => {
        const devMode = argv.mode !== 'production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/index.js')
            ],
            devServer: {
                port: 3000, //端口號
            },
            module: {
                rules: [
                    // ...
                    // 處理react
                    {
                        test: /\.(js|jsx)$/,
                        exclude: /node_modules/,
                        use: {
                            loader: "babel-loader"
                        }
                    },
                    // 處理less
                    {
                        test: /\.less$/,
                        use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader',
                            'postcss-loader',
                            'less-loader',
                        ]
                    }
                ]
            }
        }
    };
複製代碼

基本上搭建完這個項目了,若是你想看完整代碼

使用 webpack 4 創建 vue 項目

一樣地,咱們模仿 vue-cli 的結構,本身搭建一個 vue 項目,此次咱們的css預編譯語言用 scss

├── public
  │   └── index.html      # html 模板
  ├── src
  │   ├── assets          # 靜態資源
  │   │   └── logo.png
  │   ├── components      # 組件
  │   │   └── App.vue
  │   ├── main.js        # 入口文件
  │   ├── main.js        # 入口文件
  │   └── styles
  │       └── index.scss
  ├── .babelrc
  ├── package-lock.json
  ├── package.json
  ├── postcss.config.js
  └── webpack.config.js
複製代碼

在以上的基礎(項目搭建部分),再安裝vue相關模塊及sass模塊:

npm i vue --save
    npm i vue-loader vue-template-compiler --save-dev
    npm i node-sass sass-loader --save-dev
複製代碼
// webpack.config.js
    const path = require('path');
    const VueLoaderPlugin = require('vue-loader/lib/plugin')

    module.exports = (env, argv) => {
        const devMode = argv.mode !== 'production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/main.js')
            ],
            module: {
                rules: [
                    // ...
                    // 解析vue
                    {
                        test: /\.vue$/,
                        loader: 'vue-loader',
                        options: {
                            loaders: {}
                        }
                    },
                    // 處理scss
                    {
                        test: /\.scss$/,
                        use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader',
                            'postcss-loader',
                            'sass-loader',
                        ]
                    }
                ]
            },
            plugins: [
                // ...
                new VueLoaderPlugin()
            ]
        }
    };
複製代碼

一個簡易的 vue-cli 也搭建完成,若是你想看完整代碼

參考資源

相關文章
相關標籤/搜索