使用webpack2.0 搭建前端項目

  • 什麼是webpack:

webpack能夠看作是模塊打包機:它作的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包爲合適的格式以供瀏覽器使用。css

注意: 目前最新爲webpack2.0版本,與1.0有一些出入html

  • 初始化項目
npm init

npm install webpack --save-dev
  • 安裝loader,stylus以及postCss
npm install style-loader css-loader stylus-loader stylus --save-dev
npm install --save-dev postcss-loader autoprefixer
  • 目錄結構大體以下

  • 添加webpack.config.js 配置以下:
// 該配置基於webpack2.0 詳情查看 https://webpack.js.org/guides/migrating/
const path = require('path'); // 導入路徑包

module.exports = {
    entry: './src/main.js', //入口文件
    output: {
        path: path.resolve(__dirname, 'build'), // 指定打包以後的文件夾
     // publicPath: '/assets/', // 指定資源文件引用的目錄,也就是說用/assests/這個路徑指代path,開啓這個配置的話,index.html中應該要引用的路徑所有改成'/assets/...'
// filename: 'bundle.js' // 指定打包爲一個文件 bundle.js filename: '[name].js' // 能夠打包爲多個文件 }, // 使用loader模塊 module: { /* 在webpack2.0版本已經將 module.loaders 改成 module.rules 爲了兼容性考慮之前的聲明方法任然可用,
      同時鏈式loader(用!鏈接)只適用於module.loader,
      同時-loader不可省略
*/ rules: [{ test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { // modules: true // 設置css模塊化,詳情參考https://github.com/css-modules/css-modules } }, { loader: 'postcss-loader', // 在這裏進行配置,也能夠在postcss.config.js中進行配置,詳情參考https://github.com/postcss/postcss-loader options: { plugins: function() { return [ require('autoprefixer') ]; } } } ] }, { test: /\.styl(us)?$/, use: [ 'style-loader', 'css-loader', { loader: "postcss-loader", options: { plugins: function() { return [ require('autoprefixer') ]; } } }, 'stylus-loader' ] }] } }

 在index.html中引入'/build/main.js'。main.js 代碼以下node

require('./common/css/style.css'); require('./common/css/stylus.styl');react

  •  經過webpack-dev-server實現頁面的自動刷新。webpack

首先安裝webpack-dev-servergit

npm install --save-dev webpack-dev-server

而後修改package.json配置文件中:github

"scripts": {
    "start": "webpack-dev-server",
    "build": "webpack"
  }

使用npm start 啓動服務。npm的 start是一個特殊的腳本名稱,它的特殊性表如今,在命令行中使用npm start就能夠執行相關命令,若是對應的此腳本名稱不是start,想要在命令行中運行時,須要這樣用npm run {script name},因此打包命令修改成npm run build。web

這裏若是使用webpack-dev-server 命令來啓動就必須全局安裝 devServer:npm

npm install webpack-dev-server -g

在webpack的配置文件中能夠對devServer進行配置json

// 配置devServer各類參數
    devServer: {
        contentBase: "./", // 本地服務器所加載的頁面所在的目錄
        historyApiFallback: true, // 不跳轉
        inline: true // 實時刷新
    }

此時能夠監聽入口文件的改變,實時刷新頁面,然而非入口文件的改變則不會被監聽到,須要手動進行刷新。而且目標文件不包括index.html。這裏使用html-webpack-plugin插件。

 npm install html-webpack-plugin --save-dev 

修改webpack配置文件,添加如下配置:

...
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    ....,
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html' // 模版文件
        })
    ]
}

這裏記錄一下遇到的坑:首先,devServer其實讀取的是打包以後的文件,可是這些文件是存儲在內存當中(並不會顯示在build下)。而後因爲使用HtmlWebpackPlugin這個插件,它能夠自動幫你將打包的js插入模版html文件中,所以咱們要將原文件(就是做爲模版的index.html文件)中插入的main.js這行代碼去掉。而後若是開啓了publicPath這個選項,HtmlWebpackPlugin會插入publicPth選項的路徑('/assets/main.js'),devServer的index.html此時是沒法讀取到該目錄下的文件。可是奇怪的是devServer此時直接沒有插入該scripts。。不知道爲啥。。可是爲了部署的問題,cdn啥的,對開發環境和生產環境應該開啓不一樣的publicPath,也就是說開發和生產應該使用兩個不一樣的配置文件(包括sourcemap,devserver都不該該出如今生產的配置中)。詳細能夠參考https://segmentfault.com/a/1190000006151512這篇文章

  • sourcemap 讓開發更易於調試
module.exports = {
  devtool: 'eval-source-map',//配置生成Source Maps,選擇合適的選項
  ....
  }
}

  •  使用ES6語法

webpack2.0增長了對ES6模塊的支持,無需額外的配置,而且能夠與 AMD 和 CommonJS混用。webpack 2能夠分析理解全部的ES6代碼而且只在檢測到是ES6模塊時才使用tree-shaking。然而,只有import導入和export導出的模塊纔會被編譯爲ES5,若是但願全部的打包文件都編譯爲ES5,你須要使用一個轉譯器來處理剩下來的文件。這裏我使用babel。首先安裝babel:

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

在根目錄下添加.babelrc文件,並添加配置

若是bable的配置仍然爲:

{
  presets: ['es2015']
}

那麼無用的代碼也會被打包(Babel會將ES 6模塊經過commonJs模塊轉換輸出,而後webpack 2就不能進行tree-shaking分析了)。這塊兒大體原理是這樣的。。。

所以咱們將配置文件改成:

{
  "presets": [
        ["es2015", {"modules": false}]
    ]
}

而且在webpack的配置文件中加入以下loader(此處必定不能用use,不知道爲啥)

{
    test: /\.js$/,
    loader: 'babel-loader', //此處不能用use,不知道爲啥
    exclude: /node_modules/ //須要排除的目錄
}
  •  熱加載模塊(HMR)

webpack配置文件中,devServer的「inline」選項會爲入口頁面添加「熱加載」功能,「hot」選項則開啓「熱替換(Hot Module Reloading)」,即嘗試從新加載組件改變的部分(而不是從新加載整個頁面)。若是兩個參數都傳入,當資源改變時,webpack-dev-server將會先嚐試HRM(即熱替換),若是失敗則從新加載整個入口頁面。要使用HRM,首先須要在webpack配置文件中配置plugin:

 plugins: [
        ...
        new webpack.HotModuleReplacementPlugin() // 熱加載插件
    ]

到這一步,實際上改變css能夠實現hrm,然而js只會刷新整個頁面,index.html直接不刷新了。。。不知道爲啥。react能夠經過react-transform-hrm來搞定。非react框架如今考慮用webpack-dev-middleware 來嘗試一下。。參考http://www.tuicool.com/articles/22aQ7vu

  • 生產環境

 經過以上步驟基本的開發環境就搭建完畢了,那麼實際上在生產環境裏可能會有其餘的要求,例如分離js與css(目前css是打包到js中去的),例如壓縮代碼等。

首先建立一個webpack.production.config.js,而後在package.json中配置修改成:

"scripts": {
    "start": "webpack-dev-server",
    "build": "set NODE_ENV=production&&webpack --config ./webpack.production.config.js"
  }

當運行 npm run build 的時候,會設置環境變量"NODE_ENV"爲"production"。

var prod = process.env.NODE_ENV === 'production' ? true : false;

如今分別介紹幾個經常使用的插件:詳情參考 https://github.com/webpack/docs/wiki/list-of-plugins

  1. 提取公共模塊插件(webpack內置) CommonsChunkPlugin

  2. 壓縮js插件(webpack內置) UglifyJsPlugin
  3. 分離css文件: ExtractTextPlugin 注意該插件因爲和webpack2不兼容,須要指定版本。。在webpack.production.config.js 中的配置參考https://github.com/webpack-contrib/extract-text-webpack-plugin,注意與1.x版本loader的寫法不一樣。
  4. 清除文件夾: clean-webpack-plugin

 運用[hash]使得產生的文件名帶有哈希值,合理使用緩存。

至此大體的開發以及生產環境已經搭建完畢。

項目地址: https://github.com/Dyzzi/webpack-demo-project

相關文章
相關標籤/搜索