30分鐘手把手教你學webpack實戰css
閱讀目錄html
什麼是webpack? 他有什麼優勢?前端
首先對於不少剛接觸webpack人來講,確定會問webpack是什麼?它有什麼優勢?咱們爲何要使用它?帶着這些問題,咱們來總結下以下:node
Webpack是前端一個工具,可讓各個模塊進行加載,預處理,再進行打包,它能有Grunt或Gulp全部基本功能。優勢以下:react
二:如何安裝和配置webpack
首先個人項目目錄結構是:文件名叫webpack,裏面只有一個main.html,代碼以下:git
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="src/react.min.js"></script> </head> <body> <div id="content"></div> <script src="build/build.js"></script> </body> </html>
還有一個文件夾src,該文件夾存放了二個js文件;react.min.js源文件和main.js文件,main.js源碼以下:es6
/* 內容區模塊代碼 */ var ContentMode = React.createClass({ render: function(){ return ( <div className="ContentMode"> <div class="contents">{this.props.contents}</div> {this.props.children} </div> ) } }); /* 頁面div封裝 上面三個模塊 */ var Page = React.createClass({ render: function(){ return ( <div className="homepage"> <ContentMode contents ="longen">this is one comment</ContentMode > <ContentMode contents ="longen2">this is two comment</ContentMode > </div> ) } }); /* 初始化到content容器內 */ React.render( React.createElement(Page,null),document.getElementById("content") );
該代碼是React.js代碼,是react.js入門學習一中的代碼複製過來的 爲了演示;github
安裝步驟以下:web
首先咱們須要在根目錄下生成package.json文件,須要進入項目文件內根目錄下執行以下命令:npm init
如上經過一問一答的方式後會在根目錄下生成package.json文件,以下所示:
2 . 經過全局安裝webpack
執行命令以下:npm install -g webpack 以下所示:
在c盤下會生成node_modules文件夾中會包含webpack,此時此刻咱們可使用webpack命令了;
3. 配置webpack
每一個目錄下都必須有一個webpack.config.js,它的做用就比如Gulpfile.js、或者 Gruntfile.js,就是一個項目配置,告訴webpack須要作什麼。
以下是個人webpack.config.js代碼以下:
module.exports = { entry: "./src/main.js", output: { filename: "build/build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.css$/, loader: "style!css" }, //.js 文件使用 jsx-loader 來編譯處理 { test: /\.js$/, loader: "jsx-loader" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
entry 是頁面中的入口文件,好比我這邊的入口文件時main.js
output: 是指頁面經過webpack打包後生成的目標文件放在什麼地方去,我這邊是在根目錄下生成build文件夾,該文件夾內有一個build.js文件;
resolve: 定義瞭解析模塊路徑時的配置,經常使用的就是extensions; 能夠用來指定模塊的後綴,這樣在引入模塊時就不須要寫後綴,會自動補全。
plugins: 定義了須要使用的插件,好比commonsPlugin在打包多個入口文件時會提取公用的部分,生成common.js;
module.loaders:是文件的加載器,好比咱們以前react須要在頁面中引入jsx的js源碼到頁面上來,而後使用該語法,可是經過webpack打包後就不須要再引入JSXTransformer.js;看到上面的加載器;好比jsx-loader加載器就是表明JSXTransformer.js的,還有style-loader和css-loader加載器;所以在使用以前咱們須要經過命令把它引入到項目上來;所以須要以下命令生成下;
jsx-loader加載器 npm install jsx-loader --save-dev 以下:
Style-loader加載器 npm install style-loader --save-dev 以下:
css-loader 加載器 npm install css-loader --save-dev 以下:
局部安裝webpack 執行命令:npm install webpack --save-dev
咱們這邊乾脆把gulp的全局安裝和在項目中局部安裝也安裝下,稍後有用~
Gulp全局安裝 npm install -g gulp 以下:
在項目文件內,gulp局部安裝 使用命令 npm install gulp --save-dev 以下所示:
所以在咱們文件夾node_modules下生成文件以下:
如今咱們來執行命令 webpack; 以下所示:
便可在根目錄下生成一個build文件夾中build.js 以下所示:
咱們還可使用以下命令:webpack --display-error-details 命令執行,這樣的話方便出錯的時候能夠查看更詳盡的信息;好比以下:
如今咱們再來刷新下頁面;看到以下:
能夠看到頁面渲染出來了,咱們接着來看看頁面中的請求:
能夠看到只有一個文件react.min.js的源文件和build.js 咱們剛剛生成的build.js文件了,所以咱們經過webpack進行打包後,咱們如今就再也不須要和之前同樣引入JSXTransformer.js了。咱們還能夠看看build.js內生成了那些js,這裏就不貼代碼了,本身能夠看看了~
上面是使用webpack打包;如今咱們再來看看使用第二種方案來打包~
使用gulp來進行打包
咱們知道使用gulp來打包的話,那麼咱們須要在根目錄下須要新建 Gulpfile.js;
所以咱們這邊Gulpfile.js的源碼以下:
var gulp = require('gulp'); var webpack = require("gulp-webpack"); var webpackConfig = require("./webpack.config.js"); gulp.task('webpack', function () { var myConfig = Object.create(webpackConfig); return gulp .src('./src/main.js') .pipe(webpack(myConfig)) .pipe(gulp.dest('./build')); }); // 註冊缺省任務 gulp.task('default', ['webpack']);
而後webpack.config.js代碼變爲以下:
module.exports = { entry: "./src/main.js", output: { filename: "build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.css$/, loader: "style!css" }, //.js 文件使用 jsx-loader 來編譯處理 { test: /\.js$/, loader: "jsx-loader" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
便可,而後再在命令行中輸入gulp便可生成build/build.js了;以下所示:
Github上的代碼以下: https://github.com/tugenhua0707/webpack/ 本身能夠把壓縮包下載下來運行下便可。
三:理解webpack加載器
Webpack提供了一套加載器,好比css-loader,less-loader,style-loader,url-loader等,用於將不一樣的文件加載到js文件中,好比url-loader用於在js中加載png/jpg格式的圖片文件,css/style loader用於加載css文件,less-loader加載器是將less編譯成css文件;
配置加載器
module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname + '/assets/', publicPath: "/assets/" }, module: { loaders: [ {test: /.css$/, loader: 'style!css'}, {test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] } resolve: { extensions: ['', '.js', '.jsx'], //模塊別名定義,方便後續直接引用別名,無須多寫長長的地址 alias: { a : 'js/assets/a.js', // 後面直接引用 require(「a」)便可引用到模塊 b : 'js/assets/b.js', c : 'js/assets/c.js' } }, plugins: [commonsPlugin, new ExtractTextPlugin("[name].css")] }
module.loader: 其中test是正則表達式,對符合的文件名使用相應的加載器.
/.css$/會匹配 xx.css文件,可是並不適用於xx.sass或者xx.css.zip文件.
url-loader 它會將樣式中引用到的圖片轉爲模塊來處理; 配置信息的參數「?limit=8192」表示將全部小於8kb的圖片都轉爲base64形式。
entry 模塊的入口文件。依賴項數組中全部的文件會按順序打包,每一個文件進行依賴的遞歸查找,直到全部模塊都被打成包;
output:模塊的輸出文件,其中有以下參數:
filename: 打包後的文件名
path: 打包文件存放的絕對路徑。
publicPath: 網站運行時的訪問路徑。
relolve.extensions: 自動擴展文件的後綴名,好比咱們在require模塊的時候,能夠不用寫後綴名的。
relolve.alias: 模塊別名定義,方便後續直接引用別名,無須多寫長長的地址
plugins 是插件項;
四:理解less-loader加載器的使用
咱們先來理解下less-loader加載器,其餘的sass-loader也是一個意思,這邊不會對全部的預處理的css作講解,less-loader加載器是把css代碼轉化到style標籤內,動態插入到head標籤內;咱們先來看看我項目的結構以下:
咱們如今css文件下有一個main.less 代碼以下:
@base: #f938ab;
html,body {
background:@base;
}
Src文件下有一個main.js文件 此js文件時入口文件;裏面的代碼以下:
// css
require('../css/main.less');
webpack.config.js 代碼配置以下:
module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.less$/, loader: "style!css!less" } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
Gulpfile.js代碼以下(注意:這邊既能夠須要此文件使用gulp進行運行打包,也能夠不須要此文件,直接使用webpack進行打包;二種方式任選其一)。
var gulp = require('gulp'); var webpack = require("gulp-webpack"); var webpackConfig = require("./webpack.config.js"); gulp.task('webpack', function () { var myConfig = Object.create(webpackConfig); return gulp .src('./src/main.js') .pipe(webpack(myConfig)) .pipe(gulp.dest('./build')); }); // 註冊缺省任務 gulp.task('default', ['webpack']);
所以咱們須要安裝 style-loader css-loader 和 less-loader 以下所示:
安裝完成後,咱們查看咱們的項目的根目錄node_modules下多了以下幾個文件:
如上配置後,咱們進入項目後 運行下 gulp或者 webpack命令既可,在build文件夾內會生成build.js,此JS是動態生成style標籤並解釋正常的css插入到文檔head標籤內;咱們能夠運行下頁面,查看代碼看下以下:
所以咱們能夠看到頁面生效了;爲了更好的demo測試,我把代碼放到以下github上,本身能夠下載下來運行下既可: https://github.com/tugenhua0707/webpack-less-loader
五:理解babel-loader加載器的含義
babel-loader加載器能將ES6的代碼轉換成ES5代碼,這使咱們如今可使用ES6了;咱們在使用以前,咱們須要安裝babel-loader
執行命令:npm install babel-loader –save-dev 以下所示:
如上安裝完後,咱們在根目錄node_modules會生成文件,以下所示:
如今咱們能夠在webpack.config.js裏面moudle.loaders配置加載器了,以下代碼:
{test: /\.js$/, loader: 'babel', exclude: '/node_modules/'}
所以webpack.config.js代碼變成以下:
// 使用webpack打包 module.exports = { entry: "./src/main.js", output: { filename: "build.js", path: __dirname }, module: { loaders: [ {test: /\.js$/, loader: 'babel', exclude: '/node_modules/'} ] }, resolve: { extensions: ['', '.js', '.jsx'] }, plugins: [] };
下面咱們再來看看我項目中的目錄結構以下:
咱們在看看src源文件有下面幾個文件
React.min.js是react源碼,這個很少說,bind.js的ES6的代碼以下:
// es6的語法 let LOADER = true; module.exports = LOADER;
main.js 是頁面的入口文件;代碼以下:
let loader = require('./bind');
console.log(loader);
let是ES6的語法 至關於js中的var定義變量的含義; 接着打印下bind模塊中 打印爲true;
最後執行gulp以下:
在控制檯中打印true;我把源碼放在github上,有須要的同窗能夠本身下載下來運行下便可;以下github(我2年沒有使用github,如今從新使用,爲了更好的演示demo問題); https://github.com/tugenhua0707/webpack-babel-loader
六:瞭解下webpack的幾個命令
咱們下面來了解下 webpack -w
以下所示:
好比我在js文件裏面隨便增長一點代碼後,保存後,再刷新頁面便可能夠看到代碼生效了,無需從新運行webpack或者gulp,使用webpack -w 能夠實時打包。 webpack -p 的含義是對進行打包後的文件進行壓縮代碼;好比我在以前使用chrome看打包後的代碼以下:
如上能夠看到,代碼是未壓縮的,可是當我在控制檯命令行中運行 webpack -p 命令後,以下所示:
咱們如今再到控制檯上看下代碼變成已經壓縮後的代碼了,以下所示:
webpack -d 是提供未壓縮以前的源碼 方便代碼中的調式;以下所示:
當我運行如上所示後,咱們再來看看剛纔已經壓縮後的代碼變成什麼樣子呢?以下所示:
如上代碼能夠看到 咱們進行壓縮後的代碼,經過運行 webpack -d 命令後,便可還原未壓縮的代碼,這樣的話就能夠方便咱們線上調式代碼了。
咱們再來看看目錄下 會生成map文件,以下所示:
七:webpack對多個模塊依賴進行打包
經過一剛開始咱們瞭解到 webpack支持commonJS和AMD兩種模塊機制進行打包,所以咱們如今來針對代碼中使用commonJS和AMD機制進行作一個demo;
Src源文件增長module1.js module2.js module3.js 代碼分別以下:
module1.js 代碼: // module1.js require(["./module3"], function(){ console.log("Hello Webpack!"); }); Module2.js代碼以下: // module2.js,使用的是CommonJs機制導出包 module.exports = function(a, b){ return a + b; } Module3.js代碼使用AMD機制 // module3.js,使用AMD模塊機制 define(['./module2.js'], function(sum){ return console.log("1 + 2 = " + sum(1, 2)); }); // 入口文件 main.js 代碼以下: require("./module1");
咱們能夠運行下 webpack後 在根目錄下生成以下文件:
其中1.build文件夾是commonJS生成的 裏面是commonJS的代碼;咱們再查看頁面的代碼以下能夠看到:
咱們繼續查看控制檯輸出以下:
爲止咱們能夠看到webpack打包能夠支持commonJS模塊和AMD模塊。
具體的代碼 能夠查看個人github上的源碼:
https://github.com/tugenhua0707/webpack-multi-module-depend
八:如何獨立打包成樣式文件
有時候咱們不想把樣式打在腳本中,而是想獨立css出來,而後在頁面上外鏈css,這時候咱們須要 extract-text-webpack-plugin 來幫忙:咱們首先須要安裝 extract-text-webpack-plugin:以下: npm install extract-text-webpack-plugin –save-dev 以下所示:
而後在目錄下會生成以下:
如今咱們須要看看webpack.config.js 配置變成以下:
var ExtractTextPlugin = require("extract-text-webpack-plugin"); // 使用webpack打包 module.exports = { entry: "./src/main.js", output: { filename: "build.js" }, module: { loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.less$/, loader: ExtractTextPlugin.extract( 'css?sourceMap!' + 'less?sourceMap' ) } ] }, resolve: { extensions: ['', '.js', '.jsx'] }, // 內聯css提取到單獨的styles的css plugins: [new ExtractTextPlugin('styles.css')] };
配置完成後 咱們gulp運行下便可,在build文件夾內會生成2個文件,一個是build.js 處理模塊的文件 另外一個就是咱們的styles.css了;咱們查看下以下所示:
接着在html文件這樣引入便可:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="src/react.min.js"></script> <link rel="stylesheet" href="build/styles.css"/> </head> <body> <div id="content"></div> </body> </html>
在頁面上運行如下;便可看到效果:咱們能夠看下請求數:
具體的代碼demo能夠看個人github 以下:
https://github.com/tugenhua0707/extract-text-webpack-plugin
注意:node_modules模塊沒有上傳上去,git上傳不上去,總是提示Filename too long的錯誤,因此就沒有上傳,須要本身在本地安裝以下模塊:
九:如何打包成多個資源文件
咱們在開發頁面的時候,有時候須要有多個入口文件,作到文件是按需加載,這樣就可使用緩存提高性能;那麼咱們接下來須要如何配置呢?如今咱們繼續作demo,如今好比我如今的項目文件結構以下:
咱們直接看 webpack.config.js配置代碼變成以下:
module.exports = { entry: { "main": "./src/main.js", "index": "./src/index.js" }, output: { filename: "[name].bundle.js" } };
從上面的配置代碼咱們能夠看到 entry如今變成了一個對象了,而對象名也就是key會做爲下面output的filename屬性的[name]。固然entry也能夠是一個數組。
所以咱們直接 gulp運行下便可 在build文件下 生成2個入口文件 如上面的截圖所示:github源碼地址以下:
https://github.com/tugenhua0707/webpack-many-page
如今咱們能夠根據不一樣的頁面 引入不一樣的入口文件,實現按需加載文件。
十:關於對圖片的打包
咱們知道圖片是使用url-loader來加載的,咱們既能夠在css文件裏url的屬性;以下:
#content{ width:170px; height:60px; background:url('../images/1.jpg') no-repeat; }
咱們還能夠直接對元素的src屬性進行require賦值。以下代碼:
var img = document.createElement("img"); img.src = require("../image/1.jpg"); document.body.appendChild(img);
我這邊直接來說第一種在css文件裏的url屬性進行打包;
首先來看看我項目的目錄結構以下:
Css文件 main.css代碼以下:
#content{ width:170px; height:60px; background:url('../images/1.jpg') no-repeat; }
JS文件main.js代碼以下:
require('../css/main.css');
Webpack.config.js配置文件代碼以下:
// 使用webpack打包 module.exports = { entry: { "main": "./src/main.js" }, output: { path: './build/', filename: "build.js" }, module: { loaders: [ {test: /.css$/, loader: 'style!css'}, {test: /.(png|jpg)$/, loader: 'url?limit=8192'} ] } };
直接運行webpack 能夠生成build目錄,build目錄下會生成2個文件 一個是圖片打包後,另一個是build.js。接着咱們再在頁面運行下頁面,發現有一個問題,以下:
頁面調用圖片的url是根目錄下的,不是我打包後的 build文件夾下,因此會致使圖片路徑找不到的問題;所以這邊有一點點沒有完成的任務,但願有興趣的童靴能夠幫助完成~ 不過圖片確實是已經打包好了,爲了方便,咱們仍是提供github源碼吧!以下所示:
https://github.com/tugenhua0707/webpack-url-loader
十一:React開發神器:react-hot-loader
待續..... 因爲篇幅有限~~ 這個留給下篇文章講解。