Wha*_*ber 1 javascript reactjs webpack
我有一个反应应用程序(学生门户)。
我的文件夹结构如下:
\- build
- webpack.config.js
\- src
- App.js
- components\
- Login\
- Login.scss
- Login.js
- Dashboard\
- Register\
- redux\
- helpers\
Run Code Online (Sandbox Code Playgroud)
我的 webpack 非常标准。
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/app.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
},
stats: {
colors: true
},
devtool: 'source-map'
};
Run Code Online (Sandbox Code Playgroud)
我想建立在这个应用程序之上。所以我将此应用发布到 npm(本地)。我的文件夹结构现在是:
\- node_modules
- student-portal\
\ - src\
\ - build\
Run Code Online (Sandbox Code Playgroud)
我想要的是替换/扩展现有组件的能力,而不必复制现有文件。
所以,如果我创建一个新文件,我希望 webpack 使用它。如果此文件不存在,则应查看node_modules/student-portal\src.
所以 webpack 应该先查看src文件,然后查看node_modules\student-portal\src.
我尝试创建一个解析器函数:
var MyResolver = {
apply: function(resolver) {
resolver.plugin('module', function(request, callback) {
console.log(request.request); // this only consoles node_modules not .js files
});
}
};
Run Code Online (Sandbox Code Playgroud)
但这不会控制 .js 文件。我还尝试了许多其他插件,如 NormalModuleReplacementPlugin、ResolverPlugin 等,但都没有成功。
如果文件不存在,任何关于我如何利用 webpack 解析和替换路径的指针将不胜感激。理想情况下,我想扩展现有组件并让 webpack 将旧组件的路径替换为新组件的路径。
我认为您可以使用这些resolve.modules选项,因为它符合您的描述。但是,由于问题是关于解析插件的,我也会尝试编写一个。
这是一个lodash作为目标模块的示例。我们可以建立这样的结构:
node_modules
`--lodash
src
|--lodash
| `-- zip.js
`-index.js
Run Code Online (Sandbox Code Playgroud)
zip.js 可以是这样的 export default () => 'local zip'
在我们的webpack.config.js,做
module.exports = {
...
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
},
...
}
Run Code Online (Sandbox Code Playgroud)
在我们的 index.js 中,让我们导入zip和isObject。
// src/index.js
import zip from 'lodash/zip';
import isObject from 'lodash/isObject';
console.log(zip()); // 'local zip'
console.log(isObject({ a: 100 })); // 'true'
Run Code Online (Sandbox Code Playgroud)
这基本上是您想要的,但不是编写自定义组件的相对路径,而是编写模块路径。
但既然问题问的是插件,让我们试一试吧!我之前评论过你的 q,但后来发现插件系统在 webpack 4 中发生了变化。我在 node v10 上,所以一些语法在旧版本中可能不起作用。
目录结构:
node_modules
`--lodash
src
|--components
| `-- zip.js
`-index.js
Run Code Online (Sandbox Code Playgroud)
首先,快速浏览一个解析插件。Webpack 允许我们利用解析管道中的多个钩子(您可以在此处查看完整列表)。我们对resolve,parsedResolve和尤其感兴趣module。我们的计划是:
1. Tap into the `resolve` hook
2. Is the resolve request points to our 'components' folder?
- If not, go to **step 3**.
- If yes, is there something there it can use?
- If not, point it to `lodash` module instead.
- If yes, go to **step 3**.
3. Continue to the next hook in the pipeline (`parsedResolve`).
Run Code Online (Sandbox Code Playgroud)
当我们点击一个钩子时,我们会得到一个非常有用的request对象和这些道具:
context: 包含发行人(到 的绝对路径index.js)path:发行人的目录(到 的绝对路径src)request: 请求字符串 ('./components/zip')有了这个,我们可以编写我们的插件:
const path = require('path');
const fs = require('fs');
class CustomResolverPlugin {
constructor ({ dir, moduleName }) {
this.dir = dir; // absolute path to our 'components' folder
this.moduleName = moduleName; // name of the module, 'lodash' in this case
}
apply(resolver) {
resolver.getHook('resolve').tapAsync('CustomResolverPlugin', (request, resolveContext, callback) => {
// 1. check if the request is point to our component folder
// resolver.join is same as path.join, but memoized
const { dir } = path.parse(resolver.join(request.path, request.request));
const match = dir === this.dir;
if (match) {
// 2. get the name of the file being requested & check if it exists.
// in import zip from `./src/components/zip`, 'zip' is the name.
const { name } = path.parse(request.request);
const pathExist = fs.existsSync(path.join(this.dir, `${name}`));
if (!pathExist) {
// create a new request object.
// we'll swap the request to something like 'lodash/zip'
const _request = {
...request,
request: `${this.moduleName}/${name}`
}
// swap the target hook to 'module' to resolve it as a module.
const _target = resolver.ensureHook('module');
return resolver.doResolve(_target, _request, null, resolveContext, callback);
}
}
// 3. otherwise continue to the next hook
const target = resolver.ensureHook('parsedResolve');
return resolver.doResolve(target, request, null, resolveContext, callback);
});
}
}
Run Code Online (Sandbox Code Playgroud)
用途 webpack.config.js
module.exports = {
...
resolve: {
plugins: [
new CustomResolverPlugin({
dir: path.resolve(__dirname, './src/components'),
moduleName: 'lodash',
}),
],
},
...
}
Run Code Online (Sandbox Code Playgroud)
在你的 index.js 中:
import zip from './components/zip';
import isObject from './components/isObject';
console.log(zip(['a', 'b'], [1, 2])); // 'local zip'
console.log(isObject({ a: 100 })); // true
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
2335 次 |
| 最近记录: |