2013-02-14 00:00:07 +08:00
/ *
MIT License http : //www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @ sokra
* /
2017-02-22 23:34:10 +08:00
"use strict" ;
2013-02-14 00:00:07 +08:00
2017-02-22 23:34:10 +08:00
const path = require ( "path" ) ;
const ParserHelpers = require ( "./ParserHelpers" ) ;
const ConstDependency = require ( "./dependencies/ConstDependency" ) ;
2014-06-16 21:18:49 +08:00
2017-02-22 23:34:10 +08:00
const NullFactory = require ( "./NullFactory" ) ;
2015-07-13 06:20:09 +08:00
2017-02-22 23:34:10 +08:00
class NodeStuffPlugin {
constructor ( options ) {
this . options = options ;
}
2015-07-13 06:20:09 +08:00
2017-02-22 23:34:10 +08:00
apply ( compiler ) {
const options = this . options ;
2017-12-06 22:01:25 +08:00
compiler . hooks . compilation . tap ( "NodeStuffPlugin" , ( compilation , {
normalModuleFactory
} ) => {
2017-02-22 23:34:10 +08:00
compilation . dependencyFactories . set ( ConstDependency , new NullFactory ( ) ) ;
compilation . dependencyTemplates . set ( ConstDependency , new ConstDependency . Template ( ) ) ;
2015-07-13 06:20:09 +08:00
2017-12-14 17:22:27 +08:00
const handler = ( parser , parserOptions ) => {
2017-02-22 23:34:10 +08:00
if ( parserOptions . node === false )
return ;
let localOptions = options ;
if ( parserOptions . node )
localOptions = Object . assign ( { } , localOptions , parserOptions . node ) ;
2016-09-14 18:04:42 +08:00
2017-11-08 18:32:05 +08:00
const setConstant = ( expressionName , value ) => {
2017-12-19 21:35:30 +08:00
parser . hooks . expression . for ( expressionName ) . tap ( "NodeStuffPlugin" , ( ) => {
2017-11-08 18:32:05 +08:00
parser . state . current . addVariable ( expressionName , JSON . stringify ( value ) ) ;
2017-02-22 23:34:10 +08:00
return true ;
} ) ;
2017-11-08 18:32:05 +08:00
} ;
2017-02-22 23:34:10 +08:00
2017-11-08 18:32:05 +08:00
const setModuleConstant = ( expressionName , fn ) => {
2017-12-19 21:35:30 +08:00
parser . hooks . expression . for ( expressionName ) . tap ( "NodeStuffPlugin" , ( ) => {
2017-11-08 18:32:05 +08:00
parser . state . current . addVariable ( expressionName , JSON . stringify ( fn ( parser . state . module ) ) ) ;
2017-02-22 23:34:10 +08:00
return true ;
} ) ;
2017-11-08 18:32:05 +08:00
} ;
2017-02-22 23:34:10 +08:00
const context = compiler . context ;
if ( localOptions . _ _filename === "mock" ) {
setConstant ( "__filename" , "/index.js" ) ;
} else if ( localOptions . _ _filename ) {
setModuleConstant ( "__filename" , module => path . relative ( context , module . resource ) ) ;
}
2017-12-19 21:35:30 +08:00
parser . hooks . evaluateIdentifier . for ( "__filename" ) . tap ( "NodeStuffPlugin" , expr => {
2017-11-08 18:32:05 +08:00
if ( ! parser . state . module ) return ;
const resource = parser . state . module . resource ;
2017-02-22 23:34:10 +08:00
const i = resource . indexOf ( "?" ) ;
return ParserHelpers . evaluateToString ( i < 0 ? resource : resource . substr ( 0 , i ) ) ( expr ) ;
2016-09-14 18:04:42 +08:00
} ) ;
2017-02-22 23:34:10 +08:00
if ( localOptions . _ _dirname === "mock" ) {
setConstant ( "__dirname" , "/" ) ;
} else if ( localOptions . _ _dirname ) {
setModuleConstant ( "__dirname" , module => path . relative ( context , module . context ) ) ;
}
2017-12-19 21:35:30 +08:00
parser . hooks . evaluateIdentifier . for ( "__dirname" ) . tap ( "NodeStuffPlugin" , expr => {
2017-11-08 18:32:05 +08:00
if ( ! parser . state . module ) return ;
return ParserHelpers . evaluateToString ( parser . state . module . context ) ( expr ) ;
2016-09-14 18:04:42 +08:00
} ) ;
2017-12-19 21:35:30 +08:00
parser . hooks . expression . for ( "require.main" ) . tap ( "NodeStuffPlugin" , ParserHelpers . toConstantDependencyWithWebpackRequire ( parser , "__webpack_require__.c[__webpack_require__.s]" ) ) ;
parser . hooks . expression . for ( "require.extensions" ) . tap ( "NodeStuffPlugin" , ParserHelpers . expressionIsUnsupported ( parser , "require.extensions is not supported by webpack. Use a loader instead." ) ) ;
parser . hooks . expression . for ( "module.loaded" ) . tap ( "NodeStuffPlugin" , expr => {
2017-12-16 22:15:02 +08:00
parser . state . module . buildMeta . moduleConcatenationBailout = "module.loaded" ;
return ParserHelpers . toConstantDependency ( parser , "module.l" ) ( expr ) ;
} ) ;
2017-12-19 21:35:30 +08:00
parser . hooks . expression . for ( "module.id" ) . tap ( "NodeStuffPlugin" , expr => {
2017-12-16 22:15:02 +08:00
parser . state . module . buildMeta . moduleConcatenationBailout = "module.id" ;
return ParserHelpers . toConstantDependency ( parser , "module.i" ) ( expr ) ;
} ) ;
2017-12-19 21:35:30 +08:00
parser . hooks . expression . for ( "module.exports" ) . tap ( "NodeStuffPlugin" , ( ) => {
2017-11-08 18:32:05 +08:00
const module = parser . state . module ;
2017-12-06 19:09:17 +08:00
const isHarmony = module . buildMeta && module . buildMeta . harmonyModule ;
2017-02-22 23:34:10 +08:00
if ( ! isHarmony )
return true ;
2016-09-14 18:04:42 +08:00
} ) ;
2017-12-19 21:35:30 +08:00
parser . hooks . evaluateIdentifier . for ( "module.hot" ) . tap ( "NodeStuffPlugin" , ParserHelpers . evaluateToIdentifier ( "module.hot" , false ) ) ;
parser . hooks . expression . for ( "module" ) . tap ( "NodeStuffPlugin" , ( ) => {
2017-11-08 18:32:05 +08:00
const module = parser . state . module ;
2017-12-06 19:09:17 +08:00
const isHarmony = module . buildMeta && module . buildMeta . harmonyModule ;
2017-02-22 23:34:10 +08:00
let moduleJsPath = path . join ( _ _dirname , ".." , "buildin" , isHarmony ? "harmony-module.js" : "module.js" ) ;
if ( module . context ) {
2017-11-08 18:32:05 +08:00
moduleJsPath = path . relative ( parser . state . module . context , moduleJsPath ) ;
2017-02-22 23:34:10 +08:00
if ( ! /^[A-Z]:/i . test ( moduleJsPath ) ) {
moduleJsPath = ` ./ ${ moduleJsPath . replace ( /\\/g , "/" ) } ` ;
}
2016-09-14 18:04:42 +08:00
}
2017-11-08 18:32:05 +08:00
return ParserHelpers . addParsedVariableToModule ( parser , "module" , ` require( ${ JSON . stringify ( moduleJsPath ) } )(module) ` ) ;
2017-02-22 23:34:10 +08:00
} ) ;
2017-12-14 17:22:27 +08:00
} ;
normalModuleFactory . hooks . parser . for ( "javascript/auto" ) . tap ( "NodeStuffPlugin" , handler ) ;
normalModuleFactory . hooks . parser . for ( "javascript/dynamic" ) . tap ( "NodeStuffPlugin" , handler ) ;
2016-09-14 18:04:42 +08:00
} ) ;
2017-02-22 23:34:10 +08:00
}
}
module . exports = NodeStuffPlugin ;