webpack(零工程構建一個前端項目)詳解

工做流程記錄:javascript

1.初始化項目:npm init -y

2.安裝webpack,vue,vue-loader

npm install webpack vue vue-loader

3.按裝以後根據警告提示,安裝css-loader,vue-template-conpiler依賴包。

npm install css-loader vue-template-compiler

項目初始化基本完成。css

一直遇到提示 install webpack-cli -D,即便安裝了也沒有用,索性直接刪除了,以後可使用。html

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    "build": "webpack --config webpack.config.js"
    只有在這裏面寫webpack他纔會調用這裏面的webpack,不然會調用全局的webpack,會致使不少版本不一樣出錯
  },

4.新建webpack.config.js

const path = require("path");//nodejs中的基本包,處理路徑的
module.exports = {
    entry: path.join(__dirname,"src/main.js"),//__dirname表明文件所在的目錄
    output: {
        filename: "bundle.js",
        path: path.join(__dirname,"dist")
    }
}

5.新建src文件,源代碼

src下新建app.vuevue

<template>
    <div id="text">{{text}}</div>
</template>

<script>
export default {
    data() {//數據
        return {
            text: "abc"
        };
    }
}
</script>


<style>

#text{color: red;}
</style>

src下新建main.jsjava

import Vue from "vue";
import App from "./app.vue";//.vue文件
//分別導進來文件

//建立根文件
const root = document.creatElement("div");
document.body.appendChild(root);
new Vue({
    render: (h) => h(App)//經過它掛載到html頁面中
}).$mount(root);//掛載到html頁面中

6.按須要添加loader

module.exports = {
    entry: path.join(__dirname,"src/main.js"),//__dirname表明文件所在的目錄
    output: {
        filename: "bundle.js",
        path: path.join(__dirname,"dist")
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: "vue-loader"
            },
            {
                test:/\.styl/,//stylus預處理
                use: [
                    "style-loader",
                    "css-loader",
                    "stylus-loader"//專門處理stylus文件,處理完成以後讓css-loader處理css,扔給上一層處理,本身處理本身。比較方面,能夠不用寫任意的括弧,標點符號。兼容css==== npm install stylus-loader stylus
                ]
            },
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ]
            },
            {
                test: /\.(gif|jpg|jpeg|png|svg)$/,
                use: [
                    {
                        loader: "url-loader",//的安裝依賴file-loader
                        options: {
                            limit: 1024,//若是文件小於1024就會把圖片轉譯成base64的代碼
                            name: "[name]-aa.[ext]"//指定輸出的名字,[name].[ext],原來的名字.擴展名,-aa是自定義的=====以後把相應的loader安裝便可。
                        }
                    }
                ]
            }
        ]
    }
}

webpack作的事情就是把不一樣的靜態資源類型打包成一個js,在html中引用js,在html引用js便可。把零碎的js打包在一塊兒減小http請求。使用模塊依賴,這樣積累,之後的項目能夠複用。node

7.在main.js中導入所須要的js,css,圖片等模塊。

import Vue from "vue";
import App from "./app.vue";//.vue文件
import "./assert/style/style.css";
import "./assert/img/123.jpg";
...

8.配置webpack-dev-server

安裝:webpack

npm install webpack-dev-server

安裝以後在package.json中設置git

"scripts": {
    "dev": "webpack-dev-server --config webpack.config.js"
}

在webpack.config.js中全局的配置。es6

module.exports = {
    target: "web",//編譯目標是web平臺
    entry: "..."
}
//判斷那個環境
//安裝一個cross-env,不一樣的平臺上運行的環境變量不同。
"build": "cross-env NODE_ENV=production webpack --config webpack.config.js",//windows: set NODE_ENV=production
"dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"
"dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --config webpack.config.js"//解決熱跟新是保存頁面屢次插入模板

在webpack.config.js中判斷:github

const isDev = process.env.NODE_ENV === "development";//判斷是否是develment,在裏面設置的環境變量都在process.env這個對象裏
const config = {
    target: "web",//編譯目標是web平臺
    entry: "..."
}
if(isDev) {
    config.devServer = {//給config添加一個對象。server是webpack2.0
        port: "8000",
        host: "0.0.0.0",//能夠經過localhost,127.0.0.1,訪問,也能夠手機測試,其餘本機內網也能夠訪問。
        overlay: {
            errors: true,//編譯時出現錯誤顯示
        },
        //熱加載hot,須要webpack的HotModuleReplacementPlugin插件
        hot: true//修改了一個組件的代碼,至渲染組件的數據,不會整個頁面刷新,安裝插件
    },
    config.plugins.push(
        new webpack.HotModuleReplacementPlugin(),//啓動這個插件,熱加載
        new webpack.NoEmitOnErrorsPlugin()
    ),
    config.devtool = "#cheap-module-eval-source-map"//映射編譯後的代碼,(.vue,es6代碼映射成瀏覽器識別的代碼)
}
module.exports = config;//總體的暴露出去

9.安裝html插件

html-webpack-plugin
webpack.config.js中全局引用:

const HTMLPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
//在config對象中添加
plugins: [
    new webpack.DefinePlugin({//自身自帶的一個插件
        "process.env": {//判斷是哪個環境,開發環境仍是生產環境
            NODE_ENV:isDev ? " 'development' " : " 'production' "//判斷環境
        }
    }),
    new HTMLPlugin();//new 就能夠了
]

安裝postcss-loader autoprefixer babel-loader babel-core

安裝以後新建.babelrc,postcss.config.js
postcss.config.js:

const autoprefixer = require("autoprefixer");
module.exports = {
    plugins: [
        autoprefixer()
    ]
}
//後處理css,經過次組建處理css,處理瀏覽器前綴的等。

babelrc:
安裝babel-preset-env babel-plugin-transform-vue-jsx

{
    "presets": [
        "env"
    ],
    "plugins": [
        "transform-vue-jsx"//專門轉化vue中的js
    ]
}
//如何使用jxs代碼的識別,

在插件中添加rules

{
    test: /\.jsx$/,
    loader: "babel-loader"
}
//須要在css-loader中添加一個對象
{
    "css-loader",
    {
        loader: "postcss-loader",
        options: {
            sourceMap: true
        }
    },//stylus-loader會自動生成sourse map,postcss-loader也會自動生成,這樣前面的生成後後面的在不生成,使用效率會很好。使用效率會很好。
    "stylus-loader"
}

.jsx文件

import "../.css";

export default {
    data() {
        return {
            author: "intelwisd"
        }
    },
    render() {
    //可使用一些js業務操做
        return (//返回標籤
            <div>{this.author}</div>
        );
    }
}

使用導入組件相同。

webpack正式環境打包的優化

把css單獨的打包出來,安裝extract-text-webpack-plugin
webpack.config.js:導入使用

const ExtractPlugin = require("extract-text-webpack-plugin");//非js打包成一個靜態文件,作瀏覽器緩存

//根據不一樣的環境去添加css 
if(isDev) {//開發時使用styl
    config.module.rules.push({
        test: /\.styl/,
        use:[
            "style-loader",
            "css-loader",
            {
                loader: "postcss-loader",
                options: {
                    sourceMap: true 
                }
            },
            'stylus-loader'
        ]
    });
}else{//線上時使用把css單獨打包成靜態文件
    config.module.rules.push({
        test: /\.styl/,
        use: ExtractPlugin.extract({
            fallback: "style-loader",
            use: [
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        sourceMap: true
                    }
                },
                "stylus-loader"
            ]
        })
    }),
    config.plugins.push(
        new ExtractPlugin("styles.[contentHash:8].css")
    ),
    config.output.filename = "[name].[chunkhash:8].js"
    //接着處理filename
}
filename: "bundle.[hash:8].js"//默認的

vue-loader會根據每一個組件裏面的樣式顯示的時候纔會顯示到頁面上,好處是使用組件異步加載的時候css跟着異步加載,會省不少流量。

單獨打包庫代碼以致於緩存

else{//線上環境
    config.entry = {//entry路徑下添加打包的庫文件
        app: path.join(__dirname,"src/index.js"),
        vendor: ["vue","vue-router"]
    },
    config.plugin.push({//利用此插件
        new webpack.optimize.CommonsChunkPlugin({
            name: "vender"//庫文件打包成的名字
        }),//這二者是有順序的
        new webpack.optimize.CommonsChunkPlugin({
            name: "runtime"//webpack相關的文件打包到包度的文件中,好處:有新的模塊時,webpack會添加一個新的id上去,就會致使打包時hash發生變化,會阻止瀏覽器的長緩存。
        })
    })
}

hash和chunkhash

chunkhash: 在entry中生成的不一樣的節點,否則打都打包沒有意義。線上環境必須用chunkhash。
hash: 全部打包出來的模塊都是同一個哈希,整個應用的hash

https://github.com/Wunworld/myWebpack1

相關文章
相關標籤/搜索