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


webpack4發布以來,我寫項目都是用腳手架,即使再簡單的項目,真的是really shame。。雖然道聽途說了很多 webpack4 的特性,卻沒有嘗試過,因為它給人的感覺就是,em...很難。但是今天我從最簡單的部分開始,一點點搭建起一個項目。

0配置,配置了什么

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

mkdir webpack-4-quickstart && cd webpack-4-quickstart npm init -y npm i webpack --save-dev npm i webpack-cli --save-dev 

修改代碼 package.jsonscripts 部分:

"scripts": { "build": "webpack" } 

現在,我們的 package.json 是這樣的:

{
  "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, 會給出以下提示/錯誤:

 

webpack4-error

 

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

entry & output

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

console.log(`I'm a entry point`); 

此時再次執行 npm run build,成功打包出了 dist/main.js,因此我們可以得知:

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

當然,如果你想覆蓋這個配置(比如修改為 ./foo/src/js/index.js),可以在 package.json 修改:

"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 之前,我們寫一個項目起碼會設置兩種類型文件:

  • 用於開發環境的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 也搭建完成,如果你想看完整代碼

參考資源

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM