webpack 4.x之搭建前端開發環境

  webpack是一個現代JavaScript應用程序的靜態模塊打包器,借用官網的一張圖,它可以將一些預處理語言,js的最新語法轉換成瀏覽器識別的內容。如今通常的前端框架都有比較成熟的腳手架,大多數對webpack都有個較好的集成,咱們只須要敲一些簡單的命令就能生成一個通用的項目模板,比較便捷,可是要知其然知其因此然,因此今天就嘗試着從零開始搭建一個前端開發環境。css

  項目源碼:html

    https://github.com/gerryli0214/webpack-demo前端

  webpack的四個核心概念:node

    一、入口(entry)webpack

    二、輸出(output)git

    三、loaderes6

    四、插件(plugins)github

  首先,咱們執行下npm init;初始化一個node工程,填寫項目的信息,整個項目的目錄結構以下:web

  

  所有安裝webpack-cli:npm

npm install webpack-cli -g

  安裝項目webpack依賴:

npm install webpack webpack-cli -D

  新建一個webpack.config.js,這個是webpack默認配置文件,在裏面咱們能夠配置打包信息,初始化文件爲:

const config = {};

module.exports = config;

  入口(entry):

    項目的入口文件,能夠配置單個/多個,爲入口文件的相對路徑,type:string/object;咱們項目入口文件爲index.js。

const config = {
    entry: './src/index.js'
}

module.exports = config;

  輸出(output):

    打包後的文件路徑和配置信息,path爲打包文件路徑,filename爲輸出文件名稱,name爲原始文件名稱,hash爲打包後的hash地址:

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash].min.js'
}

  loader:

    loader可以處理非JavaScript文件,webpack默認只能處理JavaScript文件。在使用loader時,首先要安裝下指定loader的依賴,此部分的配置規則與以前版本有所差別,具體配置以下:

npm install babel-loader css-loader -D
 module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            },
            {
                test: /\.js/,
                exclude: /node_modules/, //過濾node_modules文件夾
                use: [{
                    loader: 'babel-loader'
                }]
            }
        ]
    }

  插件(plugins):

    插件是webpack最爲強大的功能之一,利用插件,咱們能夠進行代碼的混淆、壓縮、從新定義項目環境變量等。插件分爲webpack內置插件和第三方插件,第三方插件在使用時首先要安裝依賴和導入依賴模塊。詳細的使用方法能夠參考npm。下面羅列了幾個項目中經常使用的插件:

    html-webpack-plugin:

      主要做用:

        一、爲html文件中引入的外部資源如scriptlink動態添加每次compile後的hash,防止引用緩存的外部文件問題

        二、能夠生成建立html入口文件,好比單頁面能夠生成一個html文件入口,配置多個就能夠打包成多頁面

    extract-text-webpack-plugin:

      主要做用:分離打包的css文件

    uglifyjs-webpack-plugin:

      主要做用:混淆js代碼

    webpack-bundle-analyzer:

      主要做用:生成打包文件報告,能夠看到各個模塊打包後文件大小信息

    clean-webpack-plugin:

      主要做用:每次打包以前清除dist文件夾

    配置信息以下: 

 1 const path = require('path');
 2 const webpack = require('webpack');
 3 const HtmlWebpackPlugin = require('html-webpack-plugin');
 4 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 5 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 6 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 7 const CleanWebpackPlugin = require('clean-webpack-plugin');
 8 
 9 const config = {
10     entry: './src/index.js',
11     output: {
12         path: path.resolve(__dirname, 'dist'),
13         filename: '[name].[hash].min.js'
14     },
15     module: {
16         rules: [{
17                 test: /\.css$/,
18                 use: ExtractTextPlugin.extract({
19                     fallback: 'style-loader',
20                     use: 'css-loader'
21                 })
22             },
23             {
24                 test: /\.js/,
25                 exclude: /node_modules/, //過濾node_modules文件夾
26                 use: [{
27                     loader: 'babel-loader'
28                 }]
29             }
30         ]
31     },
32     optimization: {
33         splitChunks: {
34             name: "vendor",
35             filename: 'vendor-[hash].min.js'
36         },
37         minimizer: [new UglifyJsPlugin()]
38     },
39     plugins: [
40         new HtmlWebpackPlugin({ template: './src/index.html' }),
41         new ExtractTextPlugin({
42             filename: 'build.min.css',
43             allChunks: true,
44         }),
45         new webpack.BannerPlugin({
46             banner: `構建時間:${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}`
47         }),
48         new CleanWebpackPlugin(),
49         // new webpack.EnvironmentPlugin({ NODE_ENV: 'production' }),
50         new BundleAnalyzerPlugin()
51     ]
52 };
53 
54 module.exports = config;

  以上爲打包的基礎配置信息,在咱們實際開發中,常常會用到前端開發服務,模塊熱更新以及前端的跨域請求代理,webpack中提供了webpack-dev-server來知足咱們的需求,在使用以前先安裝下webpack-dev-server的依賴:

npm install webpack-dev-server -D

  具體文件配置以下:

devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        host: '0.0.0.0',
        port: 9000,
        hot: true, //是否熱更新
        proxy: { //代理
            '/api': 'http://localhost:3000'
        }
    }

  package.json中啓動命令配置以下:

"scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "webpack-dev-server --mode development",
        "build": "webpack --mode production"
    }

  執行npm run start,執行結果以下:

  

  這樣開發環境咱們的主要配置就完成了,可是當咱們用uglifyjs壓縮es6代碼時,會發現會報錯,由於uglifyjs不能壓縮es6的代碼,此時咱們須要手動配置下babel,具體步驟以下:

  一、安裝項目依賴

npm install @babel/core @babel/preset-env -D

  二、新建在項目根目錄下.babelrc文件,填入如下配置信息

{
    "presets":["@babel/preset-env"]
}

  執行npm run build,壓縮項目代碼,結果以下:

  

  所有代碼:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CleanWebpackPlugin = require('clean-webpack-plugin');

const config = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[hash].min.js'
    },
    module: {
        rules: [{
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            },
            {
                test: /\.js/,
                exclude: /node_modules/, //過濾node_modules文件夾
                use: [{
                    loader: 'babel-loader'
                }]
            }
        ]
    },
    optimization: {
        splitChunks: {
            name: "vendor",
            filename: 'vendor-[hash].min.js'
        },
        minimizer: [new UglifyJsPlugin()]
    },
    plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' }),
        new ExtractTextPlugin({
            filename: 'build.min.css',
            allChunks: true,
        }),
        new webpack.BannerPlugin({
            banner: `構建時間:${new Date().getFullYear()}-${new Date().getMonth()+1}-${new Date().getDate()}`
        }),
        new CleanWebpackPlugin(),
        // new webpack.EnvironmentPlugin({ NODE_ENV: 'production' }),
        new BundleAnalyzerPlugin()
    ],
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        host: '0.0.0.0',
        port: 9000,
        hot: true, //是否熱更新
        proxy: { //代理
            '/api': 'http://localhost:3000'
        }
    },
    devtool: 'source-map'
};

module.exports = config;

  參考資料:

    webpack中文網:https://www.webpackjs.com

    webpack內置插件列表:https://www.webpackjs.com/plugins/

    第三方插件可自行搜索npm:https://www.npmjs.com/

  項目源碼:

    https://github.com/gerryli0214/webpack-demo

  文筆比較粗糙,若有問題,煩請指出,謝謝!

相關文章
相關標籤/搜索