How to include scripts located inside the node_mod

2019-01-03 11:26发布

I have a question concerning best practice for including node_modules into a HTML website.

Imagine I have Bootstrap inside my node_modules folder. Now for the distribution version of the website (the live version) how would I include the Bootstrap script and CSS files located inside the node_modules folder? Does it make sense to leave Bootstrap inside that folder and do something like the following?

<script src="./node_modules/bootstrap/dist/bootstrap.min.js></script>

Or would I have to add rules to my gulp file which then copy those files into my dist folder? Or would it be best to let gulp somehow completely remove the local bootstrap from my HTML file and replace it with the CDN version?

8条回答
霸刀☆藐视天下
2楼-- · 2019-01-03 12:10

The directory 'node_modules' may not be in current directory, so you should resolve the path dynamically.

var bootstrap_dir = require.resolve('bootstrap')
                           .match(/.*\/node_modules\/[^/]+\//)[0];
app.use('/scripts', express.static(bootstrap_dir + 'dist/'));
查看更多
smile是对你的礼貌
3楼-- · 2019-01-03 12:10

I didn't find any clean solutions (I don't want to expose the source of all my node_modules) so I just wrote a Powershell script to copy them:

$deps = "leaflet", "leaflet-search", "material-components-web"

foreach ($dep in $deps) {
    Copy-Item "node_modules/$dep/dist" "static/$dep" -Recurse
}
查看更多
我想做一个坏孩纸
4楼-- · 2019-01-03 12:11

As mentioned by jfriend00 you should not expose your server structure. You could copy your project dependency files to something like public/scripts. You can do this very easily with dep-linker like this:

var DepLinker = require('dep-linker');
DepLinker.copyDependenciesTo('./public/scripts')
// Done
查看更多
The star\"
5楼-- · 2019-01-03 12:18

Usually, you don't want to expose any of your internal paths for how your server is structured to the outside world. What you can is make a /scripts static route in your server that fetches its files from whatever directory they happen to reside in. So, if your files are in "./node_modules/bootstrap/dist/". Then, the script tag in your pages just looks like this:

<script src="/scripts/bootstrap.min.js"></script>

If you were using express with nodejs, a static route is as simple as this:

app.use('/scripts', express.static(__dirname + '/node_modules/bootstrap/dist/'));

Then, any browser requests from /scripts/xxx.js will automatically be fetched from your dist directory at __dirname + /node_modules/bootstrap/dist/xxx.js.

Note: Newer versions of NPM put more things at the top level, not nested so deep so if you are using a newer version of NPM, then the path names will be different than indicated in the OP's question and in the current answer. But, the concept is still the same. You find out where the files are physically located on your server drive and you make an app.use() with express.static() to make a pseudo-path to those files so you aren't exposing the actual server file system organization to the client.


If you don't want to make a static route like this, then you're probably better off just copying the public scripts to a path that your web server does treat as /scripts or whatever top level designation you want to use. Usually, you can make this copying part of your build/deployment process.


If you want to make just one particular file public in a directory and not everything found in that directory with it, then you can manually create individual routes for each file rather than use express.static() such as:

<script src="/bootstrap.min.js"></script>

And the code to create a route for that

app.get('/bootstrap.min.js', function(req, res) {
    res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});

Or, if you want to still delineate routes for scripts with /scripts, you could do this:

<script src="/scripts/bootstrap.min.js"></script>

And the code to create a route for that

app.get('/scripts/bootstrap.min.js', function(req, res) {
    res.sendFile(__dirname + '/node_modules/bootstrap/dist/bootstrap.min.js');
});
查看更多
The star\"
6楼-- · 2019-01-03 12:20

I would use the path npm module and then do something like this:

var path = require('path');
app.use('/scripts', express.static(path.join(__dirname, 'node_modules/bootstrap/dist')));
查看更多
做自己的国王
7楼-- · 2019-01-03 12:24

If you want a quick and easy solution (and you have gulp installed).

In my gulpfile.js I run a simple copy paste task that puts any files I might need into ./public/modules/ directory.

gulp.task('modules', function() {
    sources = [
      './node_modules/prismjs/prism.js',
      './node_modules/prismjs/themes/prism-dark.css',
    ]
    gulp.src( sources ).pipe(gulp.dest('./public/modules/'));
});

gulp.task('copy-modules', ['modules']);

The downside to this is that it isn't automated. However, if all you need is a few scripts and styles copied over (and kept in a list), this should do the job.

查看更多
登录 后发表回答