-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
webpack相关 #33
Comments
看webpack的立即执行函数,当require(module)的时候 |
路径查找规则import XX from 'module/xx' 错误提示
由以上可知,webpack先看module/xx对应的js/jsx/scss/无后缀文件是否存在,如果不存在,看看xx是不是一个文件夹,如果是就看看module/xx/index对应的js/jsx/css/无后缀文件是否存在 import XX from 'module/xx'
import XX from 'module/xx/index.js' |
webpack 使用less postcss的时候,loader的加载顺序有要求 { test: /\.less$/, loader: `style!css!postcss!less` }, 如果是这样 { test: /\.less$/, loader: `style!css!less!postcss` }, 回到这postcss无法解析注释符号 *** // *** |
重启webpackwebpack的启动方式
以上两种方式本质都是直接启动webpack 守护程序需要做的一件事情就是,在特定情况下重启webpack 还需注意的是,当变化比较频繁的时候,要避免webpack多次启动 let chokidar = require('chokidar')
let child_process = require('child_process')
let exec = child_process.exec
let watcherReady = false
// 用来监控文件夹变化
let watcher = chokidar.watch('./react/pages', {
ignored: /(^|[\/\\])\../,
persistent: true
});
// 新增或者删除一个指定文件,就重启webpack
watcher.on('add', path => {
if (watcherReady && path.toLowerCase().endsWith('/view.js')) {
// 杀掉当前子进程
// 启动一个新进程
console.log('新增view: 重启webpack打包')
restartWebpack()
}
}).on('unlink', path => {
if (watcherReady && path.toLowerCase().endsWith('/view.js')) {
console.log('删除view: 重启webpack打包')
restartWebpack()
}
})
.on('ready', ()=>{
watcherReady = true
})
// 启动webpack
function startWebpack(){
let child = exec('npm run __dev__')
child.stdout.on('data', data=>{
console.log(data)
})
console.log('>> child_process id: ', child.pid)
// setTimeout(()=>{
// console.log('杀掉子进程')
// child.kill()
// }, 3000)
let resolve
// 监听退出,然后关闭掉后台运行的webpack
child.on('exit', ()=>{
console.log('webpack 停止了')
// 因为webpack是在后台监听,因此需要手动关闭
exec(`ps aux | grep node | grep webpack`, (err, stdout, stdin)=>{
Promise.all(
// 找到__dir下webpack进程的pid,然后将其kill
stdout.split('\n').filter(i => i.includes(__dirname)).forEach(item=>{
let pid = item.split(/\s+/)[1]
console.log('pid: ', pid)
return new Promise((res, rej) => {
exec(`kill -9 ${pid}`, (err, stdout, stdin)=>{
console.log('??????')
res()
}).on('error', ()=>{
res()
})
})
})
).then(msg => {
resolve && resolve('stop webpack success')
}).catch(err => {
resolve && resolve('stop webpack fail')
})
})
})
return {
// 停止webpack
stop(){
child.kill()
return new Promise(res => {
resolve = res
})
}
}
}
function restartWebpack(){
webpackProcess && webpackProcess.stop().then(msg => {
console.log(msg)
if (!webpackProcess) {
webpackProcess = startWebpack()
}
})
// 确保startWebpack不会重复执行
webpackProcess = null
}
let webpackProcess = startWebpack() |
打包输出md5文件名频繁变更问题当我们新增、删除、修改文件,未依赖此文件的入口文件的output文件名也会变更
new webpack.optimize.OccurrenceOrderPlugin()
然而!!!OccurrenceOrderPlugin并无卵用!!! 终极解决方案,使用 webpack-md5-hash,它覆盖了默认的chunkhash的行为,以真正有用的字符串来计算hash,忽略系统同意module对生成文件的影响 |
webpack 2.0新功能及特性let webpack = require('webpack')
let WebpackOnBuildPlugin = require('on-build-webpack');
// 使用ExtractTextPlugin把css抽出来
let ExtractTextPlugin = require("extract-text-webpack-plugin");
let WebpackPathOrderPlugin = require('path-order-webpack-plugin');
let WebpackMd5Hash = require('webpack-md5-hash')
let notifier = require('node-notifier');
let autoprefixer = require('autoprefixer')
let exec = require('child_process').exec
let path = require('path')
let fs = require('fs')
function webpackDone(title, message, sound) {
notifier.notify({
title: title,
message: message,
sound: sound,
icon: path.resolve(__dirname, '/Users/zikong/LingYanSi.github.io/images/wangsitu.jpg')
}, function(err, respond) {
if (err)
console.error(err);
}
);
}
let entry = {
'/rv': './Rv/index.js',
'/app': './test/app.js',
// '/div': './div/index.js'
}
exec('\\rm -r dist/ ')
module.exports = {
// 是否缓存
cache: true,
// 是否监听文件变化
watch: true,
// 入口配置
entry,
// 输出配置
output: {
// 输出路径
path: 'dist',
// chunckhash 是指文件最终的md5
filename: "[name].[chunkhash:9].js",
// 块文件名称?
chunkFilename: "[name].js"
},
module: {
rules: [
// 对js/jsx文件的处理
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['es2015'], // 把es2015转译成es5,这么做的弊端在于有些浏览器已经支持了新特性,却不能使用
plugins: ['transform-object-rest-spread', 'transform-class-properties', 'transform-decorators-legacy']
}
}
]
}, {
test: /\.scss$/,
use: [
'style-loader',
'css-loader', {
loader: 'postcss-loader',
options: {
plugins: function() {
return [// require('precss'),
require('autoprefixer')];
}
}
},
'sass-loader'
]
}
]
},
externals: {},
resolve: {
extensions: [
'.js', '.jsx', '.scss', '.css'
],
// bieming
alias: {}
},
target: "web", // enum
// the environment in which the bundle should run
// changes chunk loading behavior and available modules
devtool: "source-map", // enum
// enhance debugging by adding meta info for the browser devtools
// source-map most detailed at the expense of build speed.
context: __dirname, // string (absolute path!)
// the home directory for webpack
// the entry and module.rules.loader option
// is resolved relative to this directory
// 扩展名,按先后顺序尝试查找
// 插件
plugins: [
new WebpackMd5Hash(),
new WebpackPathOrderPlugin(),
// new ExtractTextPlugin("./../css/app.css"),
// 压缩js文本8
// new webpack.optimize.UglifyJsPlugin({
// compress: {
// warnings: false
// }
// }),
// 打印日志
new WebpackOnBuildPlugin(function(stats) {
var compilation = stats.compilation;
var errors = compilation.errors;
if (errors.length > 0) {
var error = errors[0];
webpackDone(error.name, error.message, 'Glass');
} else {
var message = 'takes ' + (stats.endTime - stats.startTime) + 'ms';
var warningNumber = compilation.warnings.length;
if (warningNumber > 0) {
message += ', with ' + warningNumber + ' warning(s)';
}
webpackDone('webpack building done', message);
}
})
].filter(i => i)
} |
完了,感觉16年自己比19年的我还要喜欢技术 (function(modules) { // webpackBootstrap
// install a JSONP callback for chunk loading
function webpackJsonpCallback(data) {
var chunkIds = data[0];
var moreModules = data[1];
var executeModules = data[2];
// add "moreModules" to the modules object,
// then flag all "chunkIds" as loaded and fire callback
var moduleId, chunkId, i = 0, resolves = [];
for(;i < chunkIds.length; i++) {
chunkId = chunkIds[i];
if(installedChunks[chunkId]) {
resolves.push(installedChunks[chunkId][0]);
}
installedChunks[chunkId] = 0;
}
for(moduleId in moreModules) {
if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
modules[moduleId] = moreModules[moduleId];
}
}
if(parentJsonpFunction) parentJsonpFunction(data);
while(resolves.length) {
resolves.shift()();
}
// add entry modules from loaded chunk to deferred list
deferredModules.push.apply(deferredModules, executeModules || []);
// run deferred modules when all chunks ready
return checkDeferredModules();
};
function checkDeferredModules() {
var result;
for(var i = 0; i < deferredModules.length; i++) {
var deferredModule = deferredModules[i];
var fulfilled = true;
for(var j = 1; j < deferredModule.length; j++) {
var depId = deferredModule[j];
if(installedChunks[depId] !== 0) fulfilled = false;
}
if(fulfilled) {
deferredModules.splice(i--, 1);
result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
}
}
return result;
}
// The module cache
var installedModules = {};
// object to store loaded and loading chunks
// undefined = chunk not loaded, null = chunk preloaded/prefetched
// Promise = chunk loading, 0 = chunk loaded
var installedChunks = {
"manifest": 0
};
var deferredModules = [];
// script path function
function jsonpScriptSrc(chunkId) {
return __webpack_require__.p + "" + ({"uploadImg":"uploadImg","ADPcategorySelect":"ADPcategorySelect","categorySelect":"categorySelect","draftEditor":"draftEditor","bankListAddCard":"bankListAddCard","modules/uploadVideo/core":"modules/uploadVideo/core","addressConfig":"addressConfig"}[chunkId]||chunkId) + "." + {"uploadImg":"3e3b9ca65","ADPcategorySelect":"9dbce0ffc","categorySelect":"e1e962ee1","draftEditor":"1dee8d532","bankListAddCard":"d12207fad","modules/uploadVideo/core":"1f0c2441e","addressConfig":"a58eadf41"}[chunkId] + ".js"
}
// 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;
}
// This file contains only the entry chunk.
// The chunk loading function for additional chunks
__webpack_require__.e = function requireEnsure(chunkId) {
var promises = [];
// JSONP chunk loading for javascript
var installedChunkData = installedChunks[chunkId];
if(installedChunkData !== 0) { // 0 means "already installed".
// a Promise means "currently loading".
if(installedChunkData) {
promises.push(installedChunkData[2]);
} else {
// setup Promise in chunk cache
var promise = new Promise(function(resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
promises.push(installedChunkData[2] = promise);
// start chunk loading
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var onScriptComplete;
script.charset = 'utf-8';
script.timeout = 120;
if (__webpack_require__.nc) {
script.setAttribute("nonce", __webpack_require__.nc);
}
script.src = jsonpScriptSrc(chunkId);
onScriptComplete = function (event) {
// avoid mem leaks in IE.
script.onerror = script.onload = null;
clearTimeout(timeout);
var chunk = installedChunks[chunkId];
if(chunk !== 0) {
if(chunk) {
var errorType = event && (event.type === 'load' ? 'missing' : event.type);
var realSrc = event && event.target && event.target.src;
var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')');
error.type = errorType;
error.request = realSrc;
chunk[1](error);
}
installedChunks[chunkId] = undefined;
}
};
var timeout = setTimeout(function(){
onScriptComplete({ type: 'timeout', target: script });
}, 120000);
script.onerror = script.onload = onScriptComplete;
head.appendChild(script);
}
}
return Promise.all(promises);
};
// 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 = "";
// on error function for async loading
__webpack_require__.oe = function(err) { console.error(err); throw err; };
var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
jsonpArray.push = webpackJsonpCallback;
jsonpArray = jsonpArray.slice();
for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
var parentJsonpFunction = oldJsonpFunction;
// run deferred modules from other chunks
checkDeferredModules();
})
([]); jsonpArray.push指向的是webpackJsonpCallback |
其他entry的带包结果 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["actTmp"],{
/***/ "wpt":
/*!*****************************!*\
!*** external "window.WPT" ***!
\*****************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = window.WPT;
/***/ })
},[["./src/actComp/actViews/View.js","manifest"]]]); 如果chunkId已经被缓存的话,指定逻辑就不会被执行? |
splitChunkshttps://webpack.js.org/plugins/split-chunks-plugin/ 请仔细阅读文档 splitChunks: {
// name: 'vendor',
cacheGroups: {
default: false, // 阻止dynamic import的资源进入vendor
vendor: {
minSize: 0,
chunks: 'initial',
name: 'vendor',
enforce: true,
test(module) {
const userRequest = module.userRequest;
if (!userRequest) return false;
return vendorModulesRegex.test(userRequest) || userRequest.startsWith(packageDir) || userRequest.startsWith(mainDir);
},
},
},
} 对于一般项目使用webpack的默认配置即可 但有的时候,我们想精确控制哪些文件(npm包)可以进入vendor,那就需要做一些额外配置
|
webpack打包生成文件详解
源文件
生成文件
根据打包后的文件可以看出,生成的是一个立即执行函数,参数是,此文件的所有以来文件
假设a.js依赖了b.js c.js他们又都依赖了d.js,但d.js只会被加载一次?
The text was updated successfully, but these errors were encountered: