從理解webpack到配置

目錄

關於此文
在學習webpack以前,咱們先去了解它的做用
它與其餘其餘前端工具(gulp,grunt)有什麼差異呢
安裝
webpack.config.js 配置結果
webpack 開始簡單配置
文件結構
demo地址
參考鏈接css


關於此文

本文是筆者初學webpack後的一個簡單總結和從新思考的過程。文章中加入了更多的認識和理解,配置比較簡單,未分環境進行配置。後續會在實操後,寫一篇在開發和發佈環境下配置webpack的文章。但願能幫助到你們,有誤的地方也請多多指正 (^^ゞ 。最後,祝你們元旦快樂ヾ(≧▽≦*)ohtml

在學習webpack以前,咱們先去了解它的做用

  1. 如webpack官網所示,它分析你的項目結構將其打包成適合瀏覽器加載的模塊。但值得注意的是,webpack並不會在瀏覽器內加載解釋器,因此它屬於一個預編譯模塊的方案。
    圖片.png-27.6kB
  2. 在打包前咱們也須要作一些轉換。這些轉換主要在loader中進行(列如將scss轉換成css)。同時,在webpack中有各類各樣的功能,例如:模塊熱加載,這就須要plugin了。也由於這兩個部分,webpack 變得豐富而複雜了。

它與其餘其餘前端工具(gulp,grunt)有什麼差異呢

gulp/grunt: 他們是一箇中能優化前端流程的工具,他們也能夠轉換 scss,less,實現自動刷新頁面的功能。
webpack: 它則屬於一個預編譯模塊方案(模塊打包工具),咱們如今的前端代碼開始分模塊進行構建,則會用到import "./a.js";require ("a.js"); 等方法。可是瀏覽器是不認識這樣的方法。這事,webpack 就出現了,它採用預編譯的方式,在代碼加載到頁面前,把這些模塊引用的方式轉換成瀏覽器能夠識別的js代碼。前端

安裝

建立package.jsonnode

npm init

安裝webpack依賴webpack

// 安裝到項目目錄
npm i -D webpack

webpack.config.js 配置結果

// __dirname 是node.js一個全局變量,指向當前執行的腳本所在文件目錄。
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: path.resolve(__dirname, 'app/main.js'), // 惟一入口文件
    output: {
        path: path.resolve(__dirname, 'build'), // 打包後文件存放的位置
        filename: 'js/[name].js', // 打包後輸出文件的文件名
    },
    devServer: {
        contentBase: path.resolve(__dirname, 'build'),  // 服務器所加載的頁面目錄
        inline: true,
        port: 2333,
        hot: true,
    },
    module: {
        loaders: [
            {
                test: /\.css$/,
                use: [
                    { loader: 'style-loader' },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true, // 指定啓用css modules
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [require('autoprefixer')],  // 爲css在不一樣瀏覽器中添加前綴
                            browser: ['last 5 versions']        // 瀏覽器最新的五個版本。
                        }
                    },
                ]
            },
            {
                test: /\.less$/,
                use: [
                    { loader: 'style-loader' },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true, // 指定啓用css modules
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [require('autoprefixer')],  // 爲css在不一樣瀏覽器中添加前綴
                            browser: ['last 5 versions']        // 瀏覽器最新的五個版本。
                        }
                    },
                    { loader: 'less-loader' },
                ]
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: '/app',
                exclude: /node_modules/,
                query: { presets: ['latest'] }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'index.html'),      // 被編譯的HTML文件路徑 
            filename: path.resolve(__dirname, 'build/index.html'),  // 編譯後的HTML文件存放路徑
            inject: 'body',      // 編譯後的js被插入HTML的body中。
            title: 'webpack is great!', //能夠經過模板引入HTML文件中。
        }),
        new webpack.HotModuleReplacementPlugin(),
    ],
};

上面是咱們常見的webpack文件,這裏咱們先經過 entry, output, loader(上面代碼中的module模塊), plugins對webpack進行講解。
entry: 入口文件,告訴webpack文件入口在哪裏。可用三種方式表示,字符串,數組,對象。git

entry: path.resolve(__dirname, '/app/main.js'), // 惟一入口文件

output: 只能有一個配置文件。須要兩個基本的配置: a filename, pathgithub

output: {
        path: path.resolve(__dirname, 'build'), // 打包後文件存放的位置
        filename: 'js/[name]-[chunkhash].js', // 打包後輸出文件的文件名
}

chunkhash:不一樣模塊文件,生成不一樣的打包文件,具備獨特的標誌,在修改a.js文件後,只對a.js進行從新打包。 除了chunkhash之外, 通常出口文件爲:'bunld.js', '[name].js]', '[name]-[hash].js'。
圖片.png-27.6kBweb

publicPath
在打包後的js標籤中添加前綴。npm

output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'js/[name]-[chunkhash].js',   // 爲每個生成的js,帶上hash
        publicPath: 'http://cdn.com/'   // 在打包後的js標籤中添加前綴。
    }

效果:
圖片.png-47.5kBjson

使用上述的cdn或者hash的方式: 生成模式下更新內嵌css,html文件裏url值。

loader: 資源轉換器。(全部的資源都是模塊,例如less經過loader可轉換成css)。 test:正則。 loader:編譯方法。
plugin: 作loader沒法作到的功能,以對象形式引入。例如模塊熱加載。

webpack 開始簡單配置

咱們這裏寫一個簡單的demo。

只講解webpack中loader, plugin 中一兩個經常使用的配置,方便你們理解配置的意義。

咱們的目錄結構:
圖片.png-13.6kB

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>webpack demo1</title>
</head>
<body>
    <div id="app">
        hello, webpack !
    </div>
</body>
</html>

main.js:

const app = document.getElementById('app');
app.innerText = "change app text!";

webpack.config.js

// __dirname 是node.js一個全局變量,指向當前執行的腳本所在文件目錄。
const webpack = require('webpack');
const path = require('path');

module.exports = {
    entry: path.resolve(__dirname, 'app/main.js'), // 惟一入口文件
    output: {
        path: path.resolve(__dirname, 'build'), // 打包後文件存放的位置
        filename: 'js/[name]-[chunkhash].js', // 打包後輸出文件的文件名
    },
    module: {
    },
    plugins: [
    ],
};

咱們能夠看到,咱們並無在index.html 中插入js。因此打開index.html效果以下:
圖片.png-1.8kB
如今我要達到js能夠自動插入html的效果。

在webpack中配置html文件

安裝插件npm install -D html-webpack-plugin

htmlWebpackPlugin的相關配置

plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'index.html'),      // 被編譯的HTML文件路徑 
            filename: path.resolve(__dirname, 'build/index.html'),  // 編譯後的HTML文件存放路徑
            inject: 'body',      // 編譯後的js被插入HTML的body中。
            title: 'webpack is great!' //能夠經過模板引入HTML文件中。
        }),
    ],

而後咱們運行webpack,咱們須要在控制檯輸入:

webpack --config webpack.config.js --progress --colors

在運行webpack.config.js,(--progress)顯示它的打包模塊的進度:..%。
若是報錯 沒法識別webpack 請全局安裝webpack。
運行後咱們控制檯表現爲:
圖片.png-28kB

  1. asset: 打包生成的文件
    size:文件大小
    Chunks:打包的分塊
    Chunk Names:打包的塊名稱。
  2. 打包成功的各個模塊。

而後咱們發現 build 文件夾新增了幾個文件。
圖片.png-5.2kB
咱們打開其中index.html 會發現js已經被插入其中了。
圖片.png-8.1kB
點擊build中的index.html 咱們會發現頁面已經發生了改變。
圖片.png-0.7kB
咱們文件插入成功了!

最後,在package.json中配置運行方式。
圖片.png-7.3kB
之後咱們只須要在控制檯輸入:npm run webpack便可。

css/less/sass 的處理

安裝: npm i -D style-loader css-loader postcss-loader autoprefixer
做用:
css-loader: 處理css文件中的url()等
style-loader:將css樣式插入html。
postcss-loader: 灰常的強大,一個後處理器,有不少插件 如:autoprefixer 爲一些css屬性在不一樣瀏覽器上的引用,加上對應的前綴。

  1. 如下面的代碼爲例,loader的執行順序爲postcss-loader css-loader style-loader ,loader順序和他們執行的功能是有關的,若是打亂可能會報錯。
module: {
        loaders: [
            {
                test: /\.css$/,
                use: [
                    { loader: 'style-loader' },
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true, // 指定啓用css modules
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [require('autoprefixer')],  // 爲css在不一樣瀏覽器中添加前綴。
                            browser: ['last 5 versions']        // 瀏覽器最新的五個版本。
                        }
                    },
                ]
            },
        ]
    }
loader: 'style-loader!css-loader!postcss-loader'
loaders: ['style-loader', 'css-loader',  'postcss-loader']  // 數組處理從右到左。
}

webpack3.0之後推薦使用第一種方式,咱們在main.js 文件中引入的 css: import "./style.css"
如今咱們看執行後的效果。
image_1c2eprhag15hmvu7umla5c1qh09.png-38.2kB
css樣式被插入html中了!U•ェ•*U

若是咱們使用的是less 或者 sass只須要添加以下操做。

  1. npm i -D less-loader less
    npm i -D sass-loader sass

  2. webpack.config.js中:

修改 test:
test: /\.less$/,
在use後面添加一個對應的loader 便可。
{   loader: 'less-loader'   },
  1. 最後記得修改對應的文件後綴。

使用babel-loader 轉換ES

咱們修改main.js

import "./style.less";
const app = document.getElementById('app');
app.innerText = "change app text!";
let changeText = () => {
    return 'function change text!!###!';
}
app.innerText = changeText();

同時咱們也發現了,每次運行npm run webpack 都會打包出新的帶有hash的main.js。
能夠配置clean-webpack-plugin 來清除,但這裏咱們簡單的修改:

output: {
        path: path.resolve(__dirname, 'build'), // 打包後文件存放的位置
        filename: 'js/[name].js', // 打包後輸出文件的文件名
    },

babel轉換:

  1. npm install -D babel-loader babel-core babel-preset-latest
loaders: [
            {
                test: /\.js$/,      // 正則匹配loader對象
                loader:'babel-loader',  
                include: '/src',    // 使用babel-loader 轉換的目錄
                exclude: /node_modules/,  //排除的目錄
                query: { presets: ['latest'] }  //使用的版本控制。
            }
        ]

而後打開build中的index文件:
圖片.png-9.8kB

自動刷新+ 模塊熱加載

  1. 安裝: npm i -D webpack-dev-server,webpack-dev-server是一個小型的Node.js Express服務器。
  2. 咱們在output 後面添加一項。
devServer: {
        contentBase: path.resolve(__dirname, 'build'),  // 服務器所加載的頁面目錄
        inline: true,   
        port: 2333,
        hot: true,  //這須要配合Hot Module Replacement實現模塊熱加載。
    },
  1. 在plugins中添加一個配置項,熱模塊替換(Hot Module Replacement)只替換更新的部分,而不是頁面重載。
    它是webapck 自帶的內容,因此不須要安裝:new webpack.HotModuleReplacementPlugin()
  2. 最後咱們須要在scripts中添加配置項: 
    圖片.png-8.7kB
    而後咱們在控制檯輸入 npm run server 時,就能夠在本地起一個服務了,效果以下:
    圖片.png-6.4kB
    若是不想每次啓服務的時候打開頁面能夠修改scripts爲:
    "server": "webpack-dev-server --config webpack.config.js"

文件結構

目錄結構

圖片.png-18.4kB
package.json:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack --config webpack.config.js --progress --colors",
    "server": "webpack-dev-server --open"
  },
  "devDependencies": {
    "autoprefixer": "^7.2.3",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-latest": "^6.24.1",
    "css-loader": "^0.28.7",
    "html-webpack-plugin": "^2.30.1",
    "less": "^2.7.3",
    "less-loader": "^4.0.5",
    "postcss-loader": "^2.0.9",
    "style-loader": "^0.19.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.9.7"
  },

webpack.config.js:
webpack.config.js 配置結果.

demo地址

點擊跳轉: webpack-demo1

 參考鏈接

https://webpack.js.org
https://www.zhihu.com/question/37020798/answer/71621266
https://www.imooc.com/learn/802

相關文章
相關標籤/搜索