小實驗
我們一步步打包一個小項目看看 webpack 是如何工作的。
-
先寫一個 hello.js
function hello(messgae){ alert(messgae); }
-
然後對其打包,發現終端報錯。解決後知道在 webpack 2.0 的時候,我們打包一個 js 文件可能是這樣的,比如將 hello.js 打包爲 hello.bundle.js 。
webpack hello.js hello.bundle.js
但是在現在 webpack 4.5.0 的時候就需要指定 mode 和輸出路徑
webpack --mode=development hello.js --output-file hello.bundle.js
mode 有指定的3種值, development、production、none。區別在於 development 打包出來的東西是沒壓縮的、可讀的,production 打包出來的是壓縮的、不可讀的。
-
然後編寫一個 world.js 和 一個 style.css ,然後進行打包
require('./world.js'); require('./style.css'); function hello(messgae){ alert(messgae); } hello("hello webpack");
通過報錯信息知道, webpack 對於 css 文件並不是默認支持的,需要指定相應的 loader 對其打包。
-
所以我們繼續安裝 css-loader、style-loader。然後指定 css 文件的 loader 爲 css-loader
require('./world.js'); require('css-loader!./style.css'); function hello(messgae){ alert(messgae); } hello("hello webpack");
-
接下來設置頁面的背景顏色,發現網頁並沒有生效。這是因爲 webpack 並不知道我們的樣式如何作用到 html 中,所以我們需要指定 style-loader
//style.css body,html{ margin: 0; padding: 0; } body{ font-size: 17px; background: burlywood; }
//hello.js require('./world.js'); require('style-loader!css-loader!./style.css'); function hello(messgae){ alert(messgae); } hello("hello webpack");
-
查看網頁效果。發現函數確實執行了,背景顏色也生效了,我們寫的 css 代碼新建了一個 style標籤 被直接寫入到 html 中了。
-
說說2個 loader 的作用。
- css-loader 就是 webpack 可以處理 css 文件。
- style-loader 的作用就是將 css-loader 處理完的文件新建一個 style 標籤插入到 html 中
-
很多人會想 require(‘style-loader!css-loader!./style.css’); 我每次寫一個 css 文件,那麼都需要在前面加入 style-loader、css-loader 嗎?顯然不是,webpack 還爲我們提供了簡單寫法
require('./world.js'); // require('style-loader!css-loader!./style.css'); require('./style.css'); function hello(messgae){ alert(messgae); } hello("hello webpack");
webpack-cli 寫法爲
webpack --mode=development hello.js --output-file hello.bundle.js --module-bind 'css=style-loader!css-loader'
-
之前的做法還存在一個弊端,就是每次修改了代碼,我們都需要在終端重新運行打包命令,十分繁瑣。這裏強大的 webpack 爲我們提供了一個 option,可以監聽代碼改變然後自動打包。如下
webpack --mode=development hello.js --output-file hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch
這樣,我們在源代碼每次一修改,webpack 會自動打包
-
如果你想看到打包過程,那麼可以使用 pregress 參數。這樣在打包的時候可以看到左下角有構件的進度
webpack --mode=development hello.js --output-file hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress
-
如果像看到打包的模塊,可以使用 –display-modules
webpack --mode=development hello.js --output-file hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress --display-modules
-
如果想知道打包某個模塊的原因,可以使用 –display-reasons
webpack --mode=development hello.js --output-file hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress --display-modules --display-reasons
用 webpack.config.js 完成上述步驟
-
初始化項目,編輯 webpack.config.js
var path = require('path'); module.exports = { entry: './src/script/main.js', output:{ path: path.resolve(__dirname,'./dist/js'), filename: 'bundle.js' } }
-
有了 webpack.config.js 文件,就不需要和上面的方式一樣,指定對應的 configuration option。在終端運行 **webpack --mode=development **
-
注意:如果我們將 webpack.config.js 改名爲 webpack.dev.config.js ,然後在命令行打包,會發現沒效果。
要將 webpack.dev.config.js 同樣生效,我們需要在命令行使用下面命令。
webpack --mode=development --config webpack.dev.config.js
-
如果想像上個實驗一樣,看到打包時候的一些信息,怎麼辦呢?
可以配合 npm 的 package.json 文件中的 scripts 標籤,在下面添加 key 爲 webpack 的項,然後將命令寫到後邊。然後在命令行運行 npm run webpack
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "webpack": "webpack --config webpack.config.js --mode=development --progress --display-modules --display-reasons --colors" },
-
對於 webpack 的 entrt 主要有3種寫法,每種寫法都有不同區別。
-
如果 webpack 只有單一入口,那麼就可以是字符串。
entry: './src/script/main.js',
-
如果 webpack 有多個入口,那麼就可以是數組。
entry: ['./src/script/main.js','./src/script/a.js'],
-
如果 webpack 有多個入口,那麼可以用對象。
entry: { main: './src/script/main.js', a : './src/script/a.js' },
-
-
如果指定了多個入口,那麼執行打包會報錯,因爲 webpack 文檔說如果多個 entry,且只有一個 output 的 filename,那麼打包的結果會覆蓋。所以我們需要設置如下
When combining with the
output.library
option: If an array is passed only the last item is exported.var path = require('path'); module.exports = { entry: { main: './src/script/main.js', a : './src/script/a.js' }, output:{ path: path.resolve(__dirname,'./dist/js'), filename: '[name]-[hash].js' } }
將文件修改爲 filename: '[name]-[chunkhash].js’
會發現 hash 和 chunkhash 的輸出的文件名並不一樣
說明: chunkhash 是根據文件的內容生成的唯一標示(類似於md5生成的唯一標示、文件版本號)。如果一個資源在打包前後文本沒有變過的話,二次打包的生成的 chunkhash 是一致的。
生成項目中 html 頁面文件
對於生成的的 js,我們 html 如何使用呢?難道每次一打包,html 中的 script 需要修改 src 嗎?不是的,webpack 提供了 html-webpack-plugin
-
安裝
npm install html-webpack-plugin --save-dev
-
然後運行命令,將現有的 js 打包引入到 html 文件中
var htmlWebpackPlugin = require('html-webpack-plugin'); //... plugins: [ new htmlWebpackPlugin() ]
然後生成的文件是 webpack 幫我們生成的 html 文件。當然我們可以新建一個自己的 html 作爲模版。
plugins: [ new htmlWebpackPlugin({ template: 'index.html' }) ]
//模版 <html> <head> <titile>webpack demo</titile> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> </body> <script type="text/javascript" src="./dist/js/bundle.js" ></script> </html> //打包生成的 <html> <head> <titile>webpack demo</titile> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <script type="text/javascript" src="main-4166ec84d15023f1cd10.js"></script><script type="text/javascript" src="a-c13b6c7a7bfe7bd0293e.js"></script></body> <script type="text/javascript" src="./dist/js/bundle.js" ></script> </html>
說明:上面選中的 template 寫了 index.html 就會找到合適的文件是因爲 webpack 有個上下文參數 context,會根據上下文找到對應的 html(這裏就是根目錄)
-
上述的缺點是生成的 html 也會放在 dist/js 目錄下。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0rhV8wwB-1585763543195)(https://github.com/FantasticLBP/knowledge-kit/raw/master/[email protected])]
需要做到的效果就是 html 放在根目錄, js 放在 dist 目錄下的 js 目錄下。需要對 webpack.config.js 的 output 屬性做修改
-
output:{ path: path.resolve(__dirname,'./dist'), filename: 'js/[name]-[chunkhash].js' },
-
plugins 的參數很多可以自定義
plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'index-[hash].html', inject: 'head' }) ]
- template: 指定生成 html 的模版
- filename:指定生成 html 的命名規則
- inject :指定生成 js 的 script 插入的位置。head、body
-
如果想通過 plugins 傳值到 生成的 html,怎麼辦?
- htmlWebpackPlugin.options 對象就可以拿到傳遞過來的值
- <%= htmlWebpackPlugin.options.title %> 模版語法來拿值
//webpack.config.js plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'index.html', inject: 'head', title: 'Webpack is awesome', date : new Date() }) ]
// 模版 html <html> <head> <titile><%= htmlWebpackPlugin.options.title %></titile> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:<%= htmlWebpackPlugin.options.date %></h3> </body> </html> //生成的html <html> <head> <titile>Webpack is awesome</titile> <script type="text/javascript" src="js/main-82c7521f0a4a776cc00b.js"></script><script type="text/javascript" src="js/a-273641522fd044fc27c7.js"></script></head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:Thu Aug 02 2018 15:40:50 GMT+0800 (CST)</h3> </body> </html>
-
我們很好奇 html-webpack-plugin 可以傳遞什麼參數?或者這個對象包含什麼信息。做個測試就知道了
//模版 html <% for (var key in htmlWebpackPlugin){ %> <%= key %> <% } %> //生成的 html files options
看到最外層的節點就2個:files、options。那麼我們分別對這2個節點遍歷輸出。因爲遍歷出的 value (**htmlWebpackPlugin.files[key] **)可能是對象、數組。所以用 JSON.Stringfy(htmlWebpackPlugin.files[key]) 打印
<html> <head> <titile><%= htmlWebpackPlugin.options.title %></titile> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:<%= htmlWebpackPlugin.options.date %></h3> <% for (var key in htmlWebpackPlugin.files){ %> <%= key %> <%= JSON.stringify(htmlWebpackPlugin.files[key]) %> <% } %> <hr> <% for (var key in htmlWebpackPlugin.options){ %> <%= key %> <%= JSON.stringify(htmlWebpackPlugin.options[key]) %> <% } %> </body> </html> //生成的 html <html> <head> <titile>Webpack is awesome</titile> <script type="text/javascript" src="js/main-82c7521f0a4a776cc00b.js"></script><script type="text/javascript" src="js/a-273641522fd044fc27c7.js"></script></head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:Thu Aug 02 2018 15:51:27 GMT+0800 (CST)</h3> publicPath "" chunks {"main":{"size":28,"entry":"js/main-82c7521f0a4a776cc00b.js","hash":"82c7521f0a4a776cc00b","css":[]},"a":{"size":18,"entry":"js/a-273641522fd044fc27c7.js","hash":"273641522fd044fc27c7","css":[]} } js ["js/main-82c7521f0a4a776cc00b.js","js/a-273641522fd044fc27c7.js"] css [] manifest <hr> template "/Users/liubinpeng/Desktop/webpackdemo/Demo2/node_modules/html-webpack-plugin/lib/loader.js!/Users/liubinpeng/Desktop/webpackdemo/Demo2/index.html" templateParameters filename "index.html" hash false inject "head" compile true favicon false minify false cache true showErrors true chunks "all" excludeChunks [] chunksSortMode "auto" meta {} title "Webpack is awesome" xhtml false date "2018-08-02T07:51:27.110Z" </body> </html>
-
有時候我們想把部分 js 放到 head ,部分 js 放到 body 中。單獨通過 webpack.config.js 是沒辦法實現這個目的,結合上面的成果,我們可以拿到 htmlWebpackPlugin.files.chunks 屬性,比如將 a.js 放到 head 標籤,main.js 放到 body 標籤。
plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'index.html', inject: false, title: 'Webpack is awesome', date : new Date() }) ]
//模版 html <html> <head> <titile><%= htmlWebpackPlugin.options.title %></titile> <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.a.entry %>"></script> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:<%= htmlWebpackPlugin.options.date %></h3> <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks.a.entry %>"></script> </body> </html>
//生成 html <html> <head> <titile>Webpack is awesome</titile> <script type="text/javascript" src="js/a-273641522fd044fc27c7.js"></script> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:Thu Aug 02 2018 15:58:56 GMT+0800 (CST)</h3> <script type="text/javascript" src="js/a-273641522fd044fc27c7.js"></script> </body> </html>
需要注意的是當自定義 js 文件的位置的時候,需要將 webpack.config.js 中 plugins 下的 inject 設置爲 false
-
接下來看到的這種需求絕對很有料。前面我們看到的都是相對路徑,但是我們的產品需要上線,所以我們的 js 文件資源路徑需要改變。如下:
//webpack.config.js output:{ path: path.resolve(__dirname,'./dist'), filename: 'js/[name]-[chunkhash].js', publicPath: 'http://test.lbp.com' },
//生成的 html <html> <head> <titile>Webpack is awesome</titile> <script type="text/javascript" src="http://test.lbp.com/js/a-502c14d352874172253c.js"></script> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <h3>時間:Thu Aug 02 2018 16:25:12 GMT+0800 (CST)</h3> <script type="text/javascript" src="http://test.lbp.com/js/a-502c14d352874172253c.js"></script> </body> </html>
-
利用 webpack 我們還可以打包好的 html 做一些優化,比如刪除註釋、去掉空格.
修改 webpack.config.js 中 plugins 節點下的 htmlWebpackPlugin 的 minify 屬性
plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'index.html', inject: false, title: 'Webpack is awesome', date : new Date(), minify:{ removeComments: true, collapseWhitespace: true } }) ],
我們對 模版 html 寫一些註釋,運行 npm run webpack 後看到生成的頁面中註釋、空格都被去掉了。
-
如果想打包生成多個 html 怎麼辦?可能使用 plugins 下的 new htmlWebpackPlugin() 多來幾組配置項
plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'a.html', title: 'this is a.html', chunks: ['main','a'], inject: 'body' }), new htmlWebpackPlugin({ template: 'index.html', filename: 'b.html', title: 'this is b.html', chunks: ['main','b'], inject: 'body' }), new htmlWebpackPlugin({ template: 'index.html', filename: 'c.html', title: 'this is c.html', chunks: ['main','c'], inject: 'body' }) ]
注意:這裏我們可以指定每個生成的 filename 以及 title。實現上述需求關鍵點在於 chunks 這個屬性。用一個數組的形式來指定需要引用的 chunk。
-
上面只是實現了 a、b、c 3個頁面,如果多了的話按照上面的寫法要煩死人的。 webpack 爲我們提供了 excludeChunks 這個屬性,它指定了不需要包含的chunk。上面寫法的另一種寫法
plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'a.html', title: 'this is a.html', // chunks: ['main','a'], inject: 'body', excludeChunks: ['b','c'] }), new htmlWebpackPlugin({ template: 'index.html', filename: 'b.html', title: 'this is b.html', //chunks: ['main','b'], inject: 'body', excludeChunks: ['a','c'] }), new htmlWebpackPlugin({ template: 'index.html', filename: 'c.html', title: 'this is c.html', // chunks: ['main','c'], inject: 'body', excludeChunks: ['a','b'] }) ],
-
有種需求是:當我們需要減小首頁 HTTP 請求(提高首頁的渲染速度),也就是將一些首頁必須用到的 JS 文件用內聯的方式寫在首頁 html 的 script 標籤裏面,不重要的 js 文件通過 script 的 src 引入。要怎麼做呢?webpack 在設計之初沒想到這種需求,很多人在 github 提了很多 issue ,官方認識到這種需求,所以在後期更新的 demo 中看到了解決方案。
-
htmlWebpackPlugin.files.chunks 對象拿到的是我們在 webpack.config.js 設置過 publicPath 生成的完整路徑
-
通過截取字符串子串的方式拿到文件地址。 **htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length) **
-
compilation.assets[jsFile.substr(htmlWebpackPlugin.files.publicPath.length)].source()
在我們的項目中加以改造,爲生成的每個頁面的 header 裏面加入 main.js。在 body 部分加入除了 main.js 之外的其他 js。
//模版html <html> <head> <title><%= htmlWebpackPlugin.options.title %></title> <script type="text/javascript"> <%= compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %> </script> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <% for(var key in htmlWebpackPlugin.files.chunks){ %> <% if( key !== 'main'){ %> <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[key].entry %>"></script> <% } %> <% } %> </body> </html>
//webpack.config.js var htmlWebpackPlugin = require('html-webpack-plugin'); var path = require('path'); module.exports = { // entry: './src/script/main.js', // entry: ['./src/script/main.js','./src/script/a.js'], entry: { main: './src/script/main.js', a : './src/script/a.js', b : './src/script/b.js', c : './src/script/c.js' }, output:{ path: path.resolve(__dirname,'./dist'), filename: 'js/[name]-[hash].js', publicPath: 'http://test.lbp.com' }, plugins: [ new htmlWebpackPlugin({ template: 'index.html', filename: 'a.html', title: 'this is a.html', inject: false, excludeChunks: ['b','c'] }), new htmlWebpackPlugin({ template: 'index.html', filename: 'b.html', title: 'this is b.html', inject: false, excludeChunks: ['a','c'] }), new htmlWebpackPlugin({ template: 'index.html', filename: 'c.html', title: 'this is c.html', inject: false, excludeChunks: ['a','b'] }) ], }
爲了驗證生效,我將 main.js 加入了 alert
//main.js function helloworld(msg){ alert(msg); } helloworld("hello webpack");
看看打包後生成的 a.html
<html> <head> <title>this is a.html</title> <script type="text/javascript"> /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "http://test.lbp.com"; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/script/main.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./src/script/main.js": /*!****************************!*\ !*** ./src/script/main.js ***! \****************************/ /*! no static exports found */ /***/ (function(module, exports) { eval("function helloworld(msg){\n alert(msg);\n}\n\n\nhelloworld(\"hello webpack\");\n\n//# sourceURL=webpack:///./src/script/main.js?"); /***/ }) /******/ }); </script> </head> <body> <h2>我是 webpack 生成 html 的模版</h2> <script type="text/javascript" src="http://test.lbp.com/js/a-4caa8a542ab497f63bf8.js"></script> </body> </html>
在瀏覽器調試後發現頁面是可以正常彈出“hello webpack”
-
loader
新建項目,一步步認識 loader
-
Js loader
我們寫的項目中會用 es6,但是並不是所有的瀏覽器都支持 es6(雖然各個瀏覽器廠商每年在不斷新增對 es6 的支持),所以我們需要使用 babel 將 es6 轉換爲瀏覽器都支持的 es2015 。所以使用 babel-loader 的時候需要指定 babel 轉換的模式。loader 官方給出了2種方式
-
可以直接像 url 的 get 形式一樣,將參數傳遞在後面。
//方式1 require("babel-loader?presets=latest"); //方式2 { test: /\.png$/, loader: 'url-loader?presets=latest' }
-
寫在 query 參數裏面
{ test: /\.js$/, loader: 'babel', query: { presets: ['latest'] } }
-
其實還有一種方式:在 package.json 文件裏面添加一個 key 爲 babel。
"babel": { presets: ['latest'] }
注意:webpack 現在已經是4.5.0了。以前的版本的寫法是
module: { loaders: [ { test: /\.js$/, loader: 'babel-loader', query: { presets: ['latest'] } } ] },
現在的寫法爲
module: { rules: [ { test: /\.js$/, loader: 'babel-loader', options: { presets: ['latest'] } } ] },
注意:我們工程如果安裝的依賴非常多,node_modules 文件非常多,babel 轉換會很慢,這時候需要指定2個參數可以顯著提高速度
module: { rules: [ { test: /\.js$/, loader: 'babel-loader', options: { presets: ['latest'] }, exclude: path.resolve(__dirname,'./node_modules/'), include: path.resolve(__dirname,'./src') } ] },
-
-
css loader
打包 css 經常會用到 css-loader、style-loader。我們經常寫 flex 的時候很多瀏覽器兼容性不一致,所以我們需要加前綴,這時候需要使用 postcss-loader、autoprefixer
官網給出2種寫法
-
loader
{ test: /\.css$/, loader: 'style-loader!css-loader!postcss-loader' }
-
loaders
{ test: /\.css$/, loaders: ['style-loader','css-loader','postcss-loader'] }
如果項目中不只是使用了 css 的話,比如還使用了 less 和 sass 的話,我們需要將 css 加額外的設置
{ test: /\.css$/, use:[ 'style-loader', {loader: 'css-loader', options: {importLoaders: 1} }, { loader: 'postcss-loader', options:{ plugins:function(){ return [ require('postcss-import')(), require('autoprefixer')({browsers:['last 5 versions']}) ] } } } ] }, { test: /\.less$/, use:[ 'style-loader', {loader: 'css-loader', options: {importLoaders: 1} }, { loader: 'postcss-loader', options:{ plugins:function(){ return [ require('postcss-import')(), require('autoprefixer')({browsers:['last 5 versions']}) ] } } }, 'less-loader' ] },
-
-
處理模版
在 webpack 經常打包處理的時候會遇到模版。有普通的 html 模版,也會有 ejs 模式下的 tpl 模版
- html 模版
<html> <head> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div id="app"> </div> </body> </html>
//layer.js import './layer.less' import tpl from './layer.html' function layer(){ return { name: 'layer', tpl: tpl } } export default layer; //app.js import Layer from './components/layer/layer.js'; import './css/common.css'; const App = function(){ var dom = document.getElementById("app"); var layer = new Layer(); dom.innerHTML = layer.tpl; } new App()
-
ejs 模版
//layer.tpl <div class="layer"> <div>this is <%= name %> layr</div> <% for(var i=0;i < arr.length; i++){ %> <%= arr[i] %> <% } %> </div> //layer.js import './layer.less' import tpl from './layer.tpl' function layer(){ return { name: 'layer', tpl: tpl } } export default layer; //app.js import Layer from './components/layer/layer.js'; import './css/common.css'; const App = function(){ var dom = document.getElementById("app"); var layer = new Layer(); dom.innerHTML = layer.tpl({ name: 'john', arr: ['swift','Objective-C','JS','python'] }); } new App()