I'm using requirejs with Grunt in my project. I could able to successfully perform the folder level optimization through grunt-requirejs tool as below.
requirejs : {
std: {
options: {
mainConfigFile: 'src/js/main.js',
appDir: "src",
baseUrl: "js",
dir: "dist",
modules: [
{
name: "main"
}
],
removeCombined: true,
wrap: true,
almond: true,
replaceRequireScript: [{
files: ['dist/index.html'],
module: 'main'
}]
}
}
}
All the js files are concatenated and minified in main.js and css files in style.css. How can I rename these files main.js and style.css into something like app.min.js and app.min.css. Can I able to accomplish this using r.js or I've to use some external plugin?
Related
In my webpack project I want to bundle my project and include an example usage file with it. However when I bundle my project in this form
module.exports = {
entry: {
main: './src/main.js',
about: './src/pages/config.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
library: 'report' //makes this a global variable we can call from basic javascript page,
devtool: 'source-map',
devServer: {
port: 3001,
clientLogLevel: 'none',
stats: 'errors-only'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'] //npm install --save-dev style-loader css-loader
}
]
},
plugins: [
new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
new HtmlWebpackPlugin({
title: 'ESS Map Learning',
}),
],
};
},
The outputted file in the dist is converted or loaded into bundled code and is unreadable as an example. I am trying to find a way to load this file so it is not changed and sits in the bundle in its original format
If you want to include an example usage file along with your bundle, you can try the following two ways:
1. use CopyWebpackPlugin
With this plugin, you can copy specific files from your source project into your output folder.
First you need to install the plugin:
npm install --save-dev copy-webpack-plugin
Then in your webpack configuration file:
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
plugins: [
new CopyPlugin([
{
from: "path/to/some-example.js",
to: "" // leave blank if you want to keep the folder hierachy as in the source code, otherwise specify an output path
},
]),
]
}
More about the plugin:
Webpack Plugins: CopyWebpackPlugin
2. use the "Asset Modules" configuration
module.exports = {
module: {
rules: [
{
test: /example\.js/, // regex to match your source example file path
type: 'asset/resource', // files with this type will be copied to your output folder
generator: {
filename: 'examples/[name][ext]', // you can give a desired name for your output file, or webpack will defaultly name it with hash value
}
}
]
},
// rest of your webpack configuration
// ...
}
Caveats: I think webpack will never process your example file if it is not a dependency of any of your entry points (which is very likely the case). In this sense I guess using the CopyWebpackPlugin is more reliable.
More about asset modules:
Webpack Guides: Asset Management
Webpack Guides: Asset Modules
I have spent half a day looking for a solution and trying everything I came across.
What I want is to use imports relative to my src folder by using an #src alias. Eg.
import { GmailMgr } from '#src/google-api/GmailMgr';
The most popular way to achieve this seems to be using https://www.npmjs.com/package/tsconfig-paths-webpack-plugin
Editing tsconfig.json like this makes vs code happy:
{
"compilerOptions": {
"outDir": "./dist/", // path to output directory
"sourceMap": true, // allow sourcemap support
"strictNullChecks": true, // enable strict null checks as a best practice
"module": "CommonJS", // specify module code generation
"jsx": "react", // use typescript to transpile jsx to js
"target": "es5", // specify ECMAScript target version
"allowJs": true, // allow a partial TypeScript and JavaScript codebase
"baseUrl": "./src",
"paths": {
"#src/*":["*"]
}
},
"include": [
"./src/"
]
}
To inform webpack about the paths in tsconfig.js, I then added the TsconfigPathsPlugin to webpack.config.js as described in the readme:
const path = require("path");
const webpack = require("webpack");
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
entry: "./App.tsx",
context: path.resolve(__dirname, "src"),
mode: "development",
module: {
rules: [
{
test: /\.(t|j)sx?$/,
loader: 'ts-loader',
exclude: /node_modules/
},
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "source-map-loader"
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
resolve: {
// changed from extensions: [".js", ".jsx"]
extensions: [".ts", ".tsx", ".js", ".jsx"],
alias: {
'react-dom': '#hot-loader/react-dom',
},
plugins: [new TsconfigPathsPlugin()]
},
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 45011,
publicPath: "http://localhost:45011/dist/",
hotOnly: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devtool: "source-map"
};
When I run webpack --mode production, I can see that the files that don't use node_modules but use this #src import style are compiled so it works but I use the google api packages in one file (GmailMgr.ts in the errors) and those rely on things like fs, child_process, net and tls and for each of them, I get an error like this:
ERROR in ../node_modules/https-proxy-agent/dist/agent.js
Module not found: Error: Can't resolve 'tls' in 'D:\MartijnFiles\Documents\Programming\0502-crew\youtube4me\node_modules\https-proxy-agent\dist'
# ../node_modules/https-proxy-agent/dist/agent.js 16:30-44
# ../node_modules/https-proxy-agent/dist/index.js
# ../node_modules/gaxios/build/src/gaxios.js
# ../node_modules/gaxios/build/src/index.js
# ../node_modules/google-auth-library/build/src/transporters.js
# ../node_modules/google-auth-library/build/src/index.js
# ./google-api/GmailMgr.ts
# ./components/YTNotifications.tsx
# ./App.tsx
It looks like it's trying to find fs, etc. inside the folder of the module instead of looking for it by starting in the node_modules root. If I remove the tsconfig-paths-webpack-plugin and paths, everything is fine but I have to stick to imports like import { GmailMgr } from '../../../google-api/GmailMgr';
P.S. I have tried webpack-node-externals and it works for the errors but this is for a website so I then get errors in the browser that require doesn't exist.
I encounter the same problem, but I don't think it's related to certain api.
I think it's a bug when using tsconfig-paths-webpack-plugin with webpack5.(I suppose you are using webpack5)
I submitted a issue here: https://github.com/dividab/tsconfig-paths-webpack-plugin/issues/60
It has started to dawn on me that webpack only has trouble with modules that require node to perform (eg. fs) and a browser won't be able to do. I suppose the google api modules are intended purely for backend (while you are able to use them perfectly if you include them using in the html). I guess I'll have to split my app into front and back end.
Update: I was right in this and split it up. However, I did still use webpack for both, just with different configs. In the backend webpack, I then used target: 'node' which prevents anything that should come from node_modules from being packed.
You may need to specify the full path to src/. Rather than using TsconfigPathsPlugin, I was able to resolve the issue by using the Webpack alias property in resolve, and using path.resolve(...) to my source directory.
In webpack.config.js:
resolve: {
extensions: [ '.ts', '.js' ],
alias: {
'#src': path.resolve( __dirname, 'src' )
},
},
For some reason using the full path worked, whereas using relative paths in webpack.config.js like #src: './src' did not. I suspect this is why TsconfigPathsPlugin didn't work as it was pulling the relative path from tsconfig.json.
Sorry I'm quite new to Nuxt & Webpack. I have a Nuxt project in which everything works fine running yarn dev. But when I build using yarn build -> yarn generate, the .css files I reference in the node_modules directory (dropzone.css, flatpickr.css etc) are never included and break the site. I've tried everything but can't figure out what I'm doing wrong. Can someone point me in the right direction? Currently running Nuxt v2.11.0 with Tailwind.css. This is my nuxt.config.js file which is mostly boilerplate -
require('dotenv').config()
export default {
env: {
baseUrl: process.env.BASE_URL || '/',
apiUrl: process.env.API_URL
},
mode: 'universal',
css: [
'#/assets/css/tailwind.css',
'#/assets/fonts/caslongraphique/webfont.css',
'#/assets/fonts/turbinadobolddry/font.css',
{ src: 'nuxt-dropzone/dropzone.css', lang: 'css' },
{ src: 'vue-agile/dist/VueAgile.css', lang: 'css' },
{ src: 'flatpickr/dist/flatpickr.css', lang: 'css' },
{ src: 'flatpickr/dist/themes/airbnb.css', lang: 'css' }
],
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: '~plugins/helpers' },
{ src: '~plugins/vue-moment' },
{ src: '~plugins/vue-agile', mode: 'client' },
{ src: '~plugins/eventBus', mode: 'client' },
{ src: '~plugins/axios', mode: 'client' },
{ src: '~plugins/vuex-persist', mode: 'client' }
],
buildModules: [
// Doc: https://github.com/nuxt-community/nuxt-tailwindcss
'#nuxtjs/tailwindcss',
],
modules: [
'#nuxtjs/axios',
'#nuxtjs/dotenv',
// 'nuxt-client-init-module'
],
build: {
/*
** You can extend webpack config here
*/
extend (config, ctx) {
},
postcss: {
plugins: {
// Disable a plugin by passing false as value
'postcss-url': false,
'postcss-nested': {},
'autoprefixer': true
},
preset: {
// Change the postcss-preset-env settings
autoprefixer: {
grid: true
}
}
},
}
}
It's pretty hard to answer this without having the full project to build and run. I assume you're not using a separate webpack config file when building for production, otherwise you would have added that to the question. You seem to be using the correct syntax in the config file, so I'm guessing your css file paths are not quite right. They kinda look like the old way of doing things, you may want to confirm that they're not out of date. This old-ish github issue goes through the various things you could try, on of them being let nuxt find the "compiled" version of the css automatically for you like this:
css: [
'nuxt-dropzone',
...etc
],
Try removing all of the 3rd party css files and add them back one at a time, after the previous one works.
This example is from the official docs:
export default {
css: [
// Load a Node.js module directly (here it's a Sass file)
'bulma',
// CSS file in the project
'#/assets/css/main.css',
// SCSS file in the project
'#/assets/css/main.scss'
]
}
I'm using requirejs in my web app, and have several 3rd party libraries(e.g. jquery, underscore), and my own js files.
Here is the "main.js" which will be loaded by requirejs:
require.config({
baseUrl: 'public/js',
paths: {
jquery: '../vendor/jquery/jquery',
underscore: '../vendor/underscore/underscore',
modernizr: '../vendor/modernizr/modernizr'
},
shim: {
underscore: {
exports: "_"
},
modernizr: {
exports: "Modernizr"
}
}
});
require(['app']);
And here is my grunt config:
requirejs: {
compileJs: {
options: {
baseUrl: "src/main/resources/public/js",
mainConfigFile: "src/main/resources/public/js/main.js",
dir: "src/main/resources/public/min/js",
optimize: "uglify2",
removeCombined: true,
generateSourceMaps: true,
modules: [
{
name: "main"
}
]
}
}
}
grunt.loadNpmTasks('grunt-contrib-requirejs');
When I run the task, it will generate a minified "main.js" which contains all my own code. But I also want it to contain the 3rd libraries(jquery, underscore, modernizr).
I tried again and again, but never succeed, nor find the reason. Why and how to include them?
i'm trying to use almond.js in grunt to combine my files into on .js and uglify it.
My configuration in grunt is like this:
requirejs: {
compile: {
options: {
baseURL: "www/js/lib",
mainConfigFile: 'www/js/main.js',
name: '../../../node_modules/almond/almond',
include: '../main',
out:'../target/app.min.js',
findNestedDependencies: true,
optimize: 'uglify',
}
}
},
my main.js is this:
require.config({
baseUrl: "js/lib",
paths: {
app: '../app',
tpl: '../tpl'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'backbone-indexeddb': {
deps: ['backbone', 'IndexedDBShim']
},
'IndexedDBShim': {
deps: ['backbone']
}
}
});
If i try to run grunt requirejs i get an error:
Error: Error: ERROR: module path does not exist: project/www/js/js/lib/../../../node_modules/almond/almond.js for module named: ../../../node_modules/almond/almond. Path is relative to: project
at /project/node_modules/grunt-contrib-requirejs/node_modules/requirejs/bin/r.js:25964:35
which i do not understand, where does the second /js/ in the path come from? It does not exist in my file structure, i have my project folder set up like this
project
gruntfile
node_modules
almond
almond.js
www
index.html
js
app
lib
main.js
Oh, i'm configuring the baseurl twice, shouldn't do that. If i remove the baseurl parameter in the gruntfile it works fine.