Why we should pass watchify arguments to browserify? - browserify

From the document of watchify, I see:
When creating the browserify instance b you MUST set these properties in the constructor:
var b = browserify({ cache: {}, packageCache: {}, fullPaths: true })
The 3 parameters cache: {}, packageCache: {}, fullPaths: true are for watchify, but why we should pass them to browserify instead of passing to watchify?

They are passed to browserify because the cache and packageCache options are forwarded to module-deps.
There is a comment from the author here:
The caching options are forwarded along to module-deps: https://github.com/substack/module-deps/blob/master/index.js
The contents of cache are not modified in module-deps, so its being passed is likely to be for performance reasons. However, the contents of packageCache are modified, so it seems there is some interaction between module-deps and watchify via the shared packageCache.

Related

vue-cli-service build: validationError for new workbox-webpack-plugin options

With the following vue.config.js:
module.exports = {
pwa: {
name: 'My App',
...
workboxPluginMode: 'InjectManifest',
workboxOptions: {
swSrc: 'src/sw.js', //and I use "sw.js" in my registerServiceWorker.js file
skipWaiting: true,
clientsClaim: true,
}
}
}
The validation errors during build are that 'skipWaiting' and 'clientsClaim' are not supported parameters. Why? swSrc is from the same list of options listed here and the build doesn't complain about that option. When I remove these two options, the build works.
So I guess my question is:
skipWaiting, clientsClaim are "not a supported parameter" of what? Of webpack? of the PWA plugin? Of the workbox-webpack plugin? Where can I find the correct set of options? Thanks.
UPDATE: I do not have a .env file setting the NODE-ENV. However npm run build which I guess builds production assets works only if I remove the 2 options. The removed options in dev (npm run serve) yields NO service worker file.
You are using workbox plugin in InjectManifest mode, but pass parameters for GenerateSW.
InjectManifest mode expects an existing service-worker file to be injected and it's path defined in swSrc, while GenerateSW will create service-worker file, thus accepts different set of options (e.g. swDest, etc)
All options for each of modes can be found on the same documentation page of workbox-webpack-plugin you've posted in corresponding sections.

How to disable webpack minification for classes names

I use jasmine, karma and webpack to test my module. The webpack preprocesses my tests files before initiating tests.
In my tests I have the class Name{...} to be tested. I create new Name instance and then, in my tests I expect(myInstance.constructor.name).toBe("Name")
class Name{}
const myInstance = new Name();
describe("The object",function(){
it("should be the instance of Name class",function(){
expect(myInstance.constructor.name).toBe("Name"); // Expected 't' to be 'Name'.
})
});
But it returns failed tests. I figured out that my Name class is parsed by webpack to the t class in the bundled file and myInstance.constructor.name equals "t".
Can I prevent webpack to change the names of classes/constructors?
Have a build setup for development and production separately, whenever in development mode(which you can mention in the webpack config object), don't apply minification plugin(might be there in your webpack config).
Help links:
Bundling Modes
Minification pluin
You can use 'keep_classnames' option provided by the minification plugin to keep the class names intact.
Install Terser Plugin to customize Webpack optimization > minimizer options running:
npm i -D terser-webpack-plugin
...or in the case you use yarn:
yarn add -D terser-webpack-plugin
Then add this optimization option inside webpack.config.js:
module.exports = {
mode: ...,
resolve: ...,
target: ...,
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
},
}),
],
},
};

how to turn off console.log and warnings from webpack

I am working on a play scala project that uses webpack and react. I did copy my webpack.config.js used for development and renamed it to webpack.prod.config.js. Using this new file, I want to be able to turn off the console.log and warnings. I used:
plugins: [
new ExtractTextPlugin("styles.css"),
new webpack.NormalModuleReplacementPlugin(/debug/, process.cwd() + './emptyDebug.js')
],
performance: {
hints: false
}
but I can still see those messages. Any solutions?
Thx
You could set the stats option to 'none':
stats: 'none'
Or you could use webpack-dev-middleware and set noInfo to true. If you're using webpack-dev-server you can set noInfo to true in the config:
devServer: {
noInfo: true
}

Bundle ractive with ractive-load through Rollup

What is the correct way to import ractive and ractive-load to my rollup project? npm or github?
Currently I am using npm to install each one:
npm install --save-dev ractivejs/ractive
And
npm install --save-dev ractivejs/ractive-load
And I'm using rollup-plugin-commonjs with rollup-plugin-node-resolve to corretly bundle them (rollup.config.js in the end of the question):
import Ractive from 'ractive';
import load from 'ractive-load';
...
But it seems that ractive-load also imports other modules in its code, causing this error:
Error parsing /home/.../node_modules/rcu/src/make.js: 'import' and 'export' may only appear at the top level (2:0) in /home/.../node_modules/rcu/src/make.js
How can I correctly use Rollup and which are the right sources for this case (npm or github)?
Here is my rollup.config.js:
import commonjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/main.js',
plugins: [
nodeResolve({
jsnext: true,
main: true,
browser: true,
}),
commonjs({
sourceMap: false
}),
// uglify()
],
format: 'iife',
moduleName: 'Altiva',
dest: 'altiva.js'
};
ractive-load is intended to "read" link tags in the browser and then do AJAX requests for the component file, then it uses a library called rcu to convert the component files into usable javascript components.
What you need is a utility (that uses rcu or does equivalent work) to turn your component files into javascript files that you can run during build process then hand-off to rollup. Fortunately, it looks like there is a rollup plugin rollup-plugin-ractive designed to do just that:
rollup({
entry: 'src/main.js',
plugins: [
ractive({
// By default, all .html files are compiled
extensions: [ '.html', '.ract' ],
// You can restrict which files are compiled
// using `include` and `exclude`
include: 'src/components/**.html'
})
]
}).then(...)
There's also list of some of the available loaders here, among them are "plain vanilla js" variants as well.

Preserve original sourcemap with Browserify

Suppose I have a module whose source code is not ECMA 5 (e.g. it's Coffescript or Typescript or whatever) and is distributed in compiled form with a source map. How can I include this source map in a Browserify bundle?
For example imagine a project with a single dependency:
index.js
node_modules
typescript_module
(main.ts)
dist
main.js
main.js.map
The "main.js.map" is not consumed by browserify. That is, the browserify bundle source map maps to "main.js" instead of deferring to the original map which describes "main.ts"
For most transforms, there is a way to input source maps generated by the prior step, but is there a way to just preserve them on the original input files, when source maps already exist?
This appears to be a bug/non-feauture of Browserify:
https://github.com/substack/node-browserify/issues/772
Answering my own question because it's very hard to track down any discussion of this issue with google and no mention of it in the Browserify docs.
My setup is the following:
tsc --project tsconfig.script.json --outDir ~temp/ts
Compiles src/script.ts to ~temp/ts/script.js and ~temp/ts/script.js.map.
browserify ~temp/ts/script.js --debug | exorcist --root ../../ ~temp/bfy/script.js.map > ~temp/bfy/script.js
Compiles ~temp/ts/script.js to ~temp/bfy/script.js and ~temp/bfy/script.js.map.
sorcery --input ~temp/bfy/script.js --output dist/script.js
Reads ~temp/bfy/script.js; finds ~temp/bfy/script.js.map + ~temp/ts/script.js.map, and finally outputs dist/script.js and dist/script.js.map.
The dist/script.js.map file does reference the original src/script.ts file.
Requires Browserify, Exorcist and Sorcery (and of course CoffeeScript or TypeScript or whatever).
If you are using a TypeScript library that you have control over (for example in a lerna monorepo), you can enable the following compilerOptions in tsconfig.json:
{
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": true,
"inlineSources": true,
// ...
}
}
browserify should now use and transform the inlined source maps.
browserify will not read source maps that reference another file, it will only use inlined source maps with inlined sources. I have written about this in the referenced issue on GitHub browserify/browserify#772.
Alternatively, if you do not have control over the source of the TypeScript library, but you would still like to see the original source in DevTools, you can use the sourceify library someone mentioned in another answer. However, I had to patch it to work and I submitted a pull request. It hasn't been merged yet (at the time of writing this). If you wish to test it yourself, you can install it directly from my branch:
npm install https://github.com/jeremija/sourceify#sources-content
Make sure to use the global transform -g [ sourceify ], because the default transform (-t) in Browserify does not modify files in node_modules.
Have a look at sourceify.
Just install it:
npm i --save-dev sourceify
... and add it as a transform to package.json:
"browserify": {
"transform": [
"sourceify"
]
}
... and it Just Works.
Try the following:
var gulp = require("gulp"),
browserify = require("browserify"),
tsify = require('tsify'),
source = require("vinyl-source-stream"),
sourcemaps = require("gulp-sourcemaps"),
buffer = require("vinyl-buffer"),
uglify = require("gulp-uglify"),
header = require("gulp-header");
var settings = {
projectName : "test"
};
gulp.task("bundle", function() {
var mainTsFilePath = "src/main.ts";
var outputFolder = "bundle/src/";
var outputFileName = settings.projectName + ".min.js";
var pkg = require("./package.json");
var banner = [
"/**",
" * <%= pkg.name %> v.<%= pkg.version %> - <%= pkg.description %>",
" * Copyright (c) 2015 <%= pkg.author %>",
" * <%= pkg.license %>",
" */", ""
].join("\n");
var bundler = browserify({
debug: true,
standalone : settings.projectName
});
// TS compiler options are in tsconfig.json file
return bundler.add(mainTsFilePath)
.plugin(tsify)
.bundle()
.pipe(source(outputFileName))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(header(banner, { pkg : pkg } ))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(outputFolder));
});
Note: change the paths to match your project!