有輸入必須有輸出,今天就來輸出一下學習webpack的過程。
css
不得不先吐槽一下,比起可愛的grunt和好用的gulp,對webpack真心愛不起來!html
還有一個血的教訓:千萬不要偷懶,有問題直接去官網。。。node
本文旨在記錄學習webpack的過車和遇到的問題,適合對node和webpack基礎知識有些瞭解的開發人員,不會詳細到記錄操做命令;還有些問題無解,還請高手指教。webpack
首先貼上搭建時候各類包的版本,畢竟webpack每次升級兼容性都不太好git
操做系統:windows 10;node:v8.9.4github
搭建步驟web
一、安裝webpack,webpack-cli,webpack-dev-server html-webpack-server (webpack-cli在4.x的版本中已經被抽離,這裏須要再安裝一下);npm
對應配置: element-ui
a、在package.json的scripts中配置啓動server的命令。json
b、在webpack.config.js中配置入口,出口,以及server;
有關server的更多配置參數請參考 https://webpack.js.org/configuration/dev-server/#src/components/Sidebar/Sidebar.jsx
c、配置html-webpack-plugin,在編譯後的文件夾自動生成一個html,而且已經添加了編譯後的入口js;
配置後webpack.config.js:(這時候咱們就能夠直接用 npm run dev 來啓動服務了。)
const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry:{//入口文件,這裏能夠配置多個入口 main: path.resolve(__dirname,'src/module/index/main.js'), //plugin: path.resolve(__dirname,'src/plugin/plugin.js') }, output: {//打包後文件位置以及文件名 path: path.resolve(__dirname,'dist'), filename: '[name].js' }, devServer: {//server配置 contentBase: path.join(__dirname,"dist"), //服務指向的文件夾 port: 9000,//端口號 inline: true,//自動刷新模式配置爲inline open: true, //是否自動打開頁面 proxy: { //代理配置 "/dist": { target: "http://localhost:3000", pathRewrite: { "^/api": "" }, bypass: function(req, res, proxyOptions){ //代理過濾函數 return "" } } } }, plugins: [ new HtmlWebpackPlugin({ //配置生成新html的源html template: path.resolve(__dirname,'src/index.html') }) ] }
二、配置loader
a、安裝js處理包:babel-loader babel-ccore babel-preset-env並配置
babel-preset-env 能夠根據配置的env只編譯那些還不支持的特性,詳情請參考https://github.com/babel/babel-preset-env
{ test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory: true //配置容許緩存,加快編譯速度 } } }
b、安裝css處理包 node-sass sass-loader(代碼中使用sass,less的配置跟sass同樣,只要安裝less對應的處理插件便可)
安裝css分離處理插件 extract-webpack-text-plugin,把css樣式從html頁面摘出來放到單獨的文件中
sass-loader 依賴於 node-sass,因此這裏不要忘記安裝 node-sass;
首先引入extract-webpack-text-plugin,並new出兩個對象來,分別處理css和less,傳參爲處理後樣式的保存路徑:
const ExtractTextPlugin = require("extract-text-webpack-plugin"); const extractCss = new ExtractTextPlugin('css/[name].css'); const extractLess = new ExtractTextPlugin('css/[name].css');
module中配置loader的rules:
{ test: /\.scss$/, use: extractLess.extract(["css-loader","sass-loader"]) }, { test: /\.css$/, use: extractCss.extract({ fallback: "style-loader", use: "css-loader" }) },
plugins裏添加extractCss和extractLess插件:
plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname,'src/index.html') }), extractCss, extractLess ]
c、img,字體等文件loader安裝配置 url-loader file-loader
注意:文檔裏介紹url-loader是基於file-loader封裝的支持更多配置的loader,可是經測試發現,url-loader並不能單獨使用,須要同時安裝file-loader纔可
哪位同窗若是知道緣由還請留言,先感謝!
{//加載圖片loader配置 test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192 //大小限制 } } ] }, {//加載字體等loader配置 test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, use:{ loader: 'file-loader' } }
三、其餘插件配置
uglifyJsPlugin,這個插件在4.x的版本中,也已經被獨立出來,須要單獨安裝才能使用。
關於模塊熱加載的開啓,官方文檔中給出多種實現,這裏給出使用devServer實現方式的測試:
其餘實現方式詳情參考 https://doc.webpack-china.org/guides/hot-module-replacement
在devServer 中設置 hot: true,在plugins中添加webpack.HotModuleReplacementPlugin();
測試結果:
修改html文件:瀏覽器打出HMR字樣的提示,可是頁面並無變化:
修改js文件:編譯後頁面徹底刷新;
當我打算繼續配置多入口多頁面時,居然發現我只能循環調用 html-webpack-plugin來生成html;
到目前位置,webpack給個人感受就是編譯速度慢,文檔介紹不清晰以致於奇奇怪怪的bug一個又一個,這些感覺大概是由於學習不夠深刻,不夠細緻。
最後,貼出package.json和webpack.config.js
{ "name": "webpackOnly", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.4", "babel-preset-env": "^1.6.1", "css-loader": "^0.28.11", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "^1.1.11", "html-webpack-plugin": "^3.2.0", "node-sass": "^4.8.3", "sass-loader": "^7.0.1", "style-loader": "^0.21.0", "uglifyjs-webpack-plugin": "^1.2.5", "url-loader": "^1.0.1", "webpack": "^4.6.0", "webpack-cli": "^2.0.15", "webpack-dev-server": "^3.1.3" }, "dependencies": { "element-ui": "^2.3.6" } }
const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const ExtractTextPlugin = require("extract-text-webpack-plugin"); const extractCss = new ExtractTextPlugin('css/[name].css'); const extractLess = new ExtractTextPlugin('css/[name].css'); module.exports = { entry:{//入口文件,這裏能夠配置多個入口 main: path.resolve(__dirname,'src/module/index/main.js'), plugin: path.resolve(__dirname,'src/plugin/plugin.js') }, output: {//打包後文件位置以及文件名 path: path.resolve(__dirname,'dist'), filename: '[name].js' }, devServer: {//server配置 contentBase: path.join(__dirname,"dist"), //服務指向的文件夾 port: 9000,//端口號 inline: true,//自動刷新模式配置爲inline open: true, //是否自動打開頁面 hot: true, proxy: { //代理配置 "/dist": { target: "http://localhost:3000", pathRewrite: { "^/api": "" }, bypass: function(req, res, proxyOptions){ //代理過濾函數 return "" } } } }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname,'src/index.html') }), new UglifyJsPlugin({ uglifyOptions: { compress: false } }), new webpack.HotModuleReplacementPlugin(),//熱加載插件 extractCss, extractLess ], module: { rules: [ { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory: true //配置容許緩存,加快編譯速度 } } }, { test: /\.scss$/, use: extractLess.extract(["css-loader","sass-loader"]) /*use: [{ //不使用css抽離的配置方式 loader: 'style-loader' },{ loader: 'css-loader' },{ loader: 'sass-loader', options: { includePaths: ["src"] } }]*/ }, { test: /\.css$/, use: extractCss.extract({ fallback: "style-loader", use: "css-loader" }) }, { test: /\.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] }, { test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, use:{ loader: 'file-loader' } } ] } }