webpack 項目配置細節

故事:其實咱們在作vue開發或者react開發 或者普通的webpack項目的時候 通常可能都是直接copy以前的webpack配置文件或者腳手架,可是當讓咱們本身配置的時候 或者解讀腳手架原理的時候,特別是細節的問題 或多或少都有些迷茫,所以我記錄了webpack配置項目的細節javascript

首先須要瞭解node路徑分類

node中路徑大體分爲5類 __dirname  __filename  process.cwd()  ./ 和 ../
css

const path = require("path")
console.log(__dirname)
console.log(__filename)
console.log(process.cwd())
console.log(path.resolve('./'))
console.log(path.resolve('../'))複製代碼

執行 noed  src/main.js  結果以下html


總結:vue

__dirname : 老是返回被執行的 js 所在文件夾的絕對路徑java

 __filename:老是返回被執行的 js文件 的絕對路徑 node

process.cwd(): 老是返回運行 node 命令時所在的文件夾的絕對路徑 react

./:在 require() 中使用是跟 __dirname 的效果相同,不會由於啓動腳本的目錄不同而改變, 在其餘狀況下跟 process.cwd() 效果相同,是相對於啓動腳本所在目錄的路徑  webpack

../: 和./差很少 只是他是返回的上一級目錄 
web

注意: 在上面咱們使用了path.resolve()方法將'./'  和 '../'解析成了絕對路徑express

·

不得不說一下 node 中的path:

在node.js中,提供了一個path某塊,在這個模塊中,提供了許多使用的,可被用來處理與轉換路徑的方法與屬性。下面咱們就來對這些方法與屬性作一下介紹。

在webpack中比較經常使用的方法就是path.join()path.resolve()

const path = require("path")
console.log(path.join('src','main.js'))
console.log(path.resolve('src','main.js'))複製代碼

執行 node  src/main.js  結果以下


總結:

path.join():方法使用平臺特定的分隔符把所有給定的 path 片斷鏈接到一塊兒,並規範化生成的路徑。

path.resolve:方法會把一個路徑或路徑片斷的序列解析爲一個絕對路徑。


開始webpack

經過環境變量劃分開發環境和生產環境

"scripts": {
    "dev": "set NODE_ENV=development && node src/main.js"
  }複製代碼

----------main.js
console.log(process.env.NODE_ENV)

複製代碼

注意 node中經常使用的到的環境變量是NODE_ENV,首先查看是否存在 set NODE_ENV 若是不存在則添加環境變量 set NODE_ENV=development

執行 npm run dev 結果以下


所以 咱們經常在項目中以下設置

"scripts": {
    "dev": "set NODE_ENV=development && node build/dev-server.js",
    "build": "set NODE_ENV=production && node build/build.js"
  }

複製代碼

開發環境熱加載和熱更新

通常方法咱們都是用webpack-dev-server 作熱更新執行webpack-dev-server –config wepack.config.js   配置以下

devServer: {
    historyApiFallback: true, // 404的頁面會自動跳轉到/頁面
    inline: true, // 文件改變自動刷新頁面
    port: 8088// 服務器端口 
}

複製代碼

可是咱們在實際項目中並不會這樣作  咱們通常會使用中間件 webpack-dev-middleware  webpack-hot-middleware  express 結合使用  由於 webpack-dev-server 其實是一個輕量級的node.js express服務器,實際上至關因而一個封裝好的express的http服務器+調用webpack-dev-middleware。 所以咱們使用express服務器進行更多的擴展,結合使用其餘的中間件來響應http請求及其餘的功能這樣擴展性更好更靈活 咱們通常經過執行 node build/dev-server.js(配置文件路徑)。 中間件,是一個函數,用於訪問請求對象、響應對象和web應用中處於請求-響應循環流程中的中間件。它的功能包括:執行任何代碼、修改請求和響應對象、終結請求-響應循環和調用堆棧中的下一個中間件。

dev-server.js部分配置以下

//使用Node自帶的文件路徑工具
const path = require('path');  

//使用express
const express = require('express'); 

//使用express啓動一個服務
const app = express(); 

const webpack = require('webpack');

const config = require('../config');

const port = 8088

const webpackdevConfig = require('./webpack.dev.config.js')

//啓動webpack進行編譯
const compiler = webpack(webpackdevConfig) 


// 啓動 webpack-dev-middleware,將 編譯後的文件暫存到內存中
const devMiddleware = require('webpack-dev-middleware')(compiler, {
    publicPath: webpackdevConfig.output.publicPath
})

const hotMiddleware = require('webpack-hot-middleware')(compiler, {
    log: () => {}
})

// 服務器部署 webpack 打包的靜態資源
app.use(devMiddleware)

// 使用熱更新, 若是編譯出現錯誤會實時展現編譯錯誤
app.use(hotMiddleware)

const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)

//爲靜態資源提供響應服務
app.use(express.static('./')) 

const server = app.listen(port)   

複製代碼

一下能夠忽略

webpack.base.config.js簡單配置

const path = require('path');
const config = require('../config')
const CleanWebpackPlugin = require('clean-webpack-plugin');
const setPath = function(_path) {
    return path.posix.join(config.dev.assetsSubDirectory, _path)
}


function resolve (dir) {
	return path.join(__dirname, '..', dir)
}


module.exports = {
    resolve: {
	    alias: {
	    	'@': resolve('src')
	    }
	},
    module: {
		rules: [
			{
                test: /\.(png|jpg|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10000,
                        name: setPath('images/[name].[hash:7].[ext]')
                    }
                }]
            },
            { 
                test: /\.scss$/,
                loader: 'style-loader!css-loader!sass-loader'
            }
		]
  	},
    plugins: [
        new CleanWebpackPlugin(['dist'], { 
            root: path.resolve(__dirname, ".."),
            verbose: false 
        })
    ]
}複製代碼

webpack.dev.config.js簡單配置

const path = require('path');

const webpack = require('webpack')

const config = require('../config')

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

const webpackbaseConfig = require('./webpack.base.config.js');

const merge = require('webpack-merge')

function resolve (dir) {
	return path.join(__dirname, '..', dir)
}

const assetsSubDirectory = "static"
const oEntry = {
        'bundle':'./src/main.js',
        'vendor': './src/scripts/carousel.js'
    }
Object.keys(oEntry).forEach(function(name) {
	oEntry[name] = ['./build/dev-client'].concat(oEntry[name])
})
module.exports = merge(webpackbaseConfig,{
    entry: oEntry,
    output: {
        path: config.build.assetsRoot,
        publicPath: config.build.assetsPublicPath,
        filename: '[name].js'
    },
    devtool: '#cheap-module-eval-source-map',
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        })
    ]
}) 複製代碼

webpack.prod.config.js簡單配置

const path = require('path');

const webpack = require('webpack')

const config = require('../config')

const webpackbaseConfig = require('./webpack.base.config.js');

const ExtractTextPlugin = require('extract-text-webpack-plugin')

const CopyWebpackPlugin = require('copy-webpack-plugin')

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

const merge = require('webpack-merge')

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const setPath = function(_path) {
    return path.posix.join(config.build.assetsSubDirectory, _path)
}
var oEntry = {
        'bundle':'./src/main.js',
        'vendor': './src/scripts/carousel.js'
   	}
module.exports = merge(webpackbaseConfig,{
    entry: oEntry,
    output: {
      	path: config.build.assetsRoot,
      	publicPath: config.build.assetsPublicPath,
    	filename: setPath('js/[name].[chunkhash].js')
    },
    module: {
    	rules: [
    		{
	            test: /\.scss$/,
	            use: ExtractTextPlugin.extract({
	                fallback: "style-loader",
	                use: [
	                	{
	                		loader:'css-loader'
	                	},
	                	{
	                		loader:'sass-loader'
	                	}
	                ]
	            })
	        },
	        {
	      test: /\.html$/,
	      loader: 'html-withimg-loader'
	    }
    	]
    },
	plugins: [
		new webpack.DefinePlugin({
			"process.env" : {
				NODE_ENV : "production"
			}
		}),
		new HtmlWebpackPlugin({
			filename: config.build.index,
			template: 'index.html',
			inject: true,
			minify: {
		        collapseWhitespace: true,
		        collapseInlineTagWhitespace: true,
		        removeComments: true,
		        removeRedundantAttributes: true
		   	}
		}),
		new webpack.optimize.UglifyJsPlugin({
			compress: {
				warnings: false
			},
			sourceMap: true
	    }),
        new ExtractTextPlugin({
            filename: setPath('css/[name].[contenthash].css')
        })/*,
	    new CopyWebpackPlugin([
			{
				from: path.resolve(__dirname, '../static'),
				to: config.build.assetsSubDirectory,
				ignore: ['.*']
			}
	    ])*/
	]
})複製代碼
相關文章
相關標籤/搜索