webpack的學習感悟

https://github.com/webpack/webpack    webpack gethub地址。javascript

http://webpack.github.io/   webpack 官網css

前言

webpack做爲如今比較火的前端框架,能夠打包js、css、html、less、jade等文件,而且應用比較普遍。甚至一些比較火的前端框架都在使用webpack打包工具,例如vue,react等等。本着互聯網的分享精神,我就將我本身的理解和想法分享給你們。html

安裝

安裝以前若是會用cnpm的儘可能用cnpm這樣會快一點,本案例默認電腦上沒有安裝cnpm鏡像。前端

一、設置全局webpackvue

npm install -g webpackjava

二、進入目標文件夾,本人使用文件目錄(E:\webpack-test)node

cd  E:\webpack-testreact

三、在項目中引導建立一個package.json文件 webpack

npm init  (初始化過程就默認按回車就好了)git

四、安裝webpack

npm install webpack --save-dev   ( --save-dev 安裝包信息將加入到devDependencies(開發階段的依賴),因此開發階段通常使用它) 安裝完成後會在項目目錄下出現node_module文件夾就證實安裝成功了

 跟我一塊兒使用

案例1

一、在項目目錄下新建一個test1.js文件 ,隨便寫一個函數。而後進行打包

function test(){
    console.log('1')
}

二、開始打包

在命令行內輸入webpack test1.js(文件入口)   test-pack.js(打包完成名字)

三、打包完成

  打包完成後命令行會返回幾個參數,一、Hash - 哈希值二、Version - webpack的版本、 Time:打包耗費時長。

  另外還返回一個列表Asset - 此次生成的文件、Size - 打包後的大小、Chunks - 此次打包的分塊、Chunk Name  - 此次打包的塊名稱。

四、打開test-pack.js文件

咱們發現,文件好像比沒有打包以前大了,由於webpack打包以前會生成一些須要的內置函數,在頁面的最下方能夠看見咱們打包的代碼。

webpack打包css文件 

注意webpack中在js文件內是能夠引用css文件的。

一、新建一個css文件名稱叫作style.css

  在裏面隨便寫一些css代碼。

二、在test.js文件中引用css

  test.js所有代碼

require('./style.css')
function test() {
    console.log('1')
}

三、打包css 可是打包以前須要安裝css-loader、 和style-loader不然會報錯。

  npm install css-loader style-loader  --save-dev    style-loader 是讓css生效,生效後的效果就是在html頁面的head標籤裏自動新建style標籤並插入代碼(這個之後的案例會講)、css-loader是讓打包軟件識別css並處理css文件。

四、運行打包命令

  webpack test1.js test-pack.js  - 可是還會報錯提示- You may need an appropriate loader to handle this file type 明明已經安裝了loader怎麼還報錯呢。

  解決錯誤,根目錄也就是webpack-test 下新建webpack.config.js文件寫入以下代碼。便可解決。錯誤緣由是沒有指定loader。

var Webpack = require("webpack");
module.exports = {
    module: {
        loaders: [
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            }
        ]
    }
}

  或者引入css時候增長css-loader!,前綴便可

require('css-loader!./style.css');

五、打包完成

打包完成後咱們看test-pack文件中又多出了好多webpack引入的一些代碼,在代碼的中間部分能夠看見咱們剛纔寫的css,這說明咱們的css已經引入成功了。

 如何實現多文件打包

  在一些單頁面應用中通常都會打包成一個文件,那例如像官網(舉例)那種也能夠打包成爲多頁應用。可是要如何配置呢。很簡單隻須要配置webpack.config.js文件便可。

  代碼以下,配置完成後 在命令行內輸入 webpack 就能夠了,由於已經配置了webpack.config.js。就不用像上面案例那樣輸入很長一段語句了。

var path = require('path') //這裏是引入了node.js的path模塊,
module.exports = {
    entry: {
        main1:'./src/script/main.js',    //若是這的value指定的是一個數組,那麼就至關於將兩個文件打包成一個文件。
        main2:'./src/script/main2.js',
    }, //多文件入口文件配置  若是是單文件只須要寫一個.string路徑便可。
    output: {
        path: path.resolve(__dirname, './dist/js'), //打包後的文件的絕對路徑地址
        filename: '[name].js' //打包後的文件名稱[name]就像當月entry下的key(main1)還有hash、chunkhash等選項,但通常不怎麼用因此呢,就不僅拿name舉例了。若是這裏不寫[]變量佔位符而是一個普通的字符串的話打包文件會被覆蓋,最後只會留下最後打包那個文件。
    },
};

 

chunkhash使用後文件生成動態名稱,那麼script要怎麼引用呢。html-webpack-plugin

  在一些大型項目中須要上傳到服務器遠程倉庫,這時候chunkhash就很是有效,由於chunkhash是當文件修改後他纔會發生改變,對代碼的控制性比較強。可是chunkhash改變後 script 的引用名稱也須要進行更改,這樣作是否是很麻煩呢,可是有一種方法能夠解決。請看代碼。

  一、安裝 npm install html-webpack-plugin --save-dev

var path = require('path');
var htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        main1: './src/script/main.js',
        main2: './src/script/main2.js',
    }, //多文件入口文件配置  若是是單文件只須要寫一個.string路徑便可。
    output: {
        path: path.resolve(__dirname, './dist/js'), //打包後的文件地址
        filename: '[name]-[chunkhash].js' //打包後的文件名稱[name]就像當月entry下的key(main1)
    },
    plugins: [
        new htmlWebpackPlugin({
            template: 'index.html',  //指定模板文件,若是不指定的話會自動生成一個新建的index.html文件一塊兒打包到path指定的打包地址。若是指定了的話,會將指定的模板打包後放入path指定的打包地址,而後自動使用script的 src引入entry下的全部文件
            minify:{ //代碼壓縮
                removeComments:true,  //刪除代碼內的註釋
                collapseWhitespace:true,//刪除代碼內的空格
            }
        })
    ]
};

 使用html-webpack-plugin打包多html文件

使用html-webpack-plugin打包多文件其實很簡單,由於plugins接收的是一個數組。因此只要多new htmlwebpackPlugin便可。

  請看代碼

var path = require('path');
var htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        main1: './src/script/main.js',
        a: './src/script/a.js',
        b: './src/script/b.js',
        c: './src/script/c.js',
    }, //多文件入口文件配置  若是是單文件只須要寫一個.string路徑便可。
    output: {
        path: path.resolve(__dirname, './dist/js'), //打包後的文件地址
        filename: '[name]-[chunkhash].js' //打包後的文件名稱[name]就像當月entry下的key(main1)
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: "a.html",  //打包後的html文件名稱 
            template: 'index.html',   //理解爲要打包那個文件,其實這裏專業解釋是使用那個模板。
            inject: 'body',    // 將JavaScript模塊放在那個標籤下,
            chunks: ['a', 'main1']//要使用那個JavaScript模塊   也但是使用excludeChunks,excludeChunks和chunks相反,excludeChunks是排除entey下的那個模塊的使用,例如 excludeChunks: ['a']  那麼就是除了a意外entry下的模塊都使用。
        }),
        new htmlWebpackPlugin({
            filename: "b.html",
            template: 'index.html',
            inject: 'body',
            chunks: ['b']
        }),
        new htmlWebpackPlugin({
            filename: "c.html",
            template: 'index.html',
            inject: 'body',
            chunks: ['c']
        })
    ]
};

 使用babel-loader將要es6語法轉換爲es5語法

安裝

npm  install  babel-loader babel-core  babel-preset-latest --save-dev

設置 webpack.config.js文件。 打包完成後就將es6語法轉換爲es語法了。

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, './dist/js'),
        filename: 'js/[name].bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude:  path.resolve(__dirname, './node_modules'), //排除那些文件不打包 include 制定打包那些
                query: {
                    presets: ['latest']   //這裏能夠指定想轉換爲何語法。例如2015 
                }
            },
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            }
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'body'     //將js文件插入body文件內
        })
    ]
}

 也能夠將配置信息寫在package中

注意: 直接寫在對象中就能夠

 "babel": {
    "presets": [
      "latest"
    ]
  },

 使用postcss-loader 實現webpack對css語法打包,並對瀏覽器兼容性樣式進行處理。

安裝:

npm install postcss-loader postcss-import  autoprefixer  cssnano --save -dev 

注意:若是沒有安裝css-loader 和style-loader 的同窗記得安裝,上述案例已經進行講解。

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, './dist/js'),
        filename: 'js/[name].bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {importLoaders: 1} //這裏能夠簡單理解爲,若是css文件中有import 進來的文件也進行處理
                    },
                    {
                        loader: 'postcss-loader',
                        options: {           // 若是沒有options這個選項將會報錯 No PostCSS Config found
                            plugins: (loader) => [
                                require('postcss-import')({root: loader.resourcePath}),
                                require('autoprefixer')(), //CSS瀏覽器兼容
                                require('cssnano')()  //壓縮css
                            ]
                        }
                    }
                ]
            }
        ]
    },

    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'body'     //將js文件插入body文件內
        }),
    ]
};

webpack怎麼實現打包less,sass

安裝

  npm install  less-loader  css-loader postcss-loader less-loader less --save-dev

webpack.config.js 代碼

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, './dist/js'),
        filename: 'js/[name].bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.less$/,     //若是使用sass的話就把less換成sass便可,但記得安裝sass-loader
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: (loader) => [
                                require('postcss-import')({root: loader.resourcePath}),
                                require('autoprefixer')(), //CSS瀏覽器兼容
                                require('cssnano')()  //壓縮css
                            ]
                        }
                    },
                    {
                        loader: 'less-loader'    //若是使用sass的話就把less換成sass便可,但記得安裝sass-loader
                    }
                ]
            },
        ]
    },
    plugins: [
        new htmlWebpackPlugin({   //配置html打包參數
            filename: 'index.html', //打包後的名字
            template: 'index.html',// 打包所使用的模板,理解爲使用的html。
            inject: 'body'     //將js文件插入body文件內
        }),
    ]
};

入口文件app.js代碼

import  './conponents/layer/layer.less'

 使用html-loader、實現對html引用的打包。

 安裝

npm install html-loader --save-dev

因爲此案例稍有些繁瑣 我將源碼發送給你們。  http://pan.baidu.com/s/1nv4Zf7r

webpack.config.js

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, './dist/js'),
        filename: 'js/[name].bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.html/,
                loader: 'html-loader'

            },
        ]
    },
    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'body'     //將js文件插入body文件內
        }),
    ]
};

入口文件app.js代碼

import layer from './conponents/layer/layer.js'
const App = function () {
    var dom = document.getElementById('app');
    var lay = new layer();
    dom.innerHTML = lay.tpl;

};
new App();

被引入文件layer代碼

import tpl from './layer.html';
import  './layer.less'
function layer() {
    return {
        name: 'layer',
        tpl: tpl
    }
}

export  default layer;

 主文件index.html代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

 怎麼對html模板進行傳參—ejs-loader

 安裝:cnpm install ejs-loader --save-dev

webpack.config.js

var htmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'js/[name].bundle.js'
    },
    module: {
        loaders: [

            {
                test: /\.tpl$/,
                loader: 'ejs-loader'
            },
            {
                test: /\.html/,
                loader: 'html-loader'

            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: (loader) => [
                                require('postcss-import')({root: loader.resourcePath}),
                                require('autoprefixer')(), //CSS瀏覽器兼容
                                require('cssnano')()  //壓縮css
                            ]
                        }
                    },
                    {
                        loader: 'less-loader'
                    }
                ]
            },
            {
                test: '/\.js$',
                loader: 'babel-loader',
                exclude: path.resolve(__dirname, './node_modules'), //排除那些文件不打包 include 制定打包那些
                query: {
                    presets: ['latest']
                }
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {importLoaders: 1} //這裏能夠簡單理解爲,若是css文件中有import 進來的文件也進行處理
                    },
                    {
                        loader: 'postcss-loader',
                        options: {           // 若是沒有options這個選項將會報錯 No PostCSS Config found
                            plugins: (loader) => [
                                require('postcss-import')({root: loader.resourcePath}),
                                require('autoprefixer')(), //CSS瀏覽器兼容
                                require('cssnano')()  //壓縮css
                            ]
                        }
                    }
                ]
            },
            {
                test: /\.(png|jpg|gif|svg)$/i,
                loaders: [
                    'url-loader?limit=20&name=assets/[name]-[hash:5].[ext]',
                    'image-webpack-loader'
                ]
                // loader: 'url-loader', //file-loader
                // query: {
                //     limit: 20000,
                //     name: 'assets/[name]-[hash:5].[ext]'
                // }
            }
        ]
    },

    plugins: [
        new htmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: 'body'     //將js文件插入body文件內
        }),
    ]
};

layer.tpl 源碼

    <div class="layer">
        <img src="${require('../../essets/bg.jpg')}" alt="">
        <div>this is<%= name %></div>
            <% for (var i = 0; i < arr.length; i++){ %>
            <%= arr[i] %>
            <% } %>
    </div>

layer.js 源碼

import tpl from './layer.tpl';
import  './layer.less'
function layer() {
    return {
        name: 'layer',
        tpl: tpl
    }
}
export  default layer;

入口文件 app.js源碼

import layer from './conponents/layer/layer.js'
const App = function () {
    var dom = document.getElementById('app');
    var lay = new layer();
    dom.innerHTML = lay.tpl({
        name: 'john',
        arr: ['a', 'b', 'c']
    });
};
new App();

若是對圖片進行壓縮或者轉換爲bese64

安裝 npm install image-webpack-loader url-loader--save-dev

固然也能夠容file-loader 代替 url-loader

limit=20000的意思是當圖片小於20000k的時候壓縮爲bese64 編碼 name=img/[name] 就是講圖片存儲到什麼位置,{name}是個佔位符,表明的事圖片原來的名字,[ext]是文件本來的後綴名。
            {
                test: /\.(png|jpg|gif|svg)$/i,
                loaders: [
                    'url-loader?limit=20000&name=img/[name].[ext]',
                    'image-webpack-loader'
                ]
            }
相關文章
相關標籤/搜索